为什么要用异步任务?

在android中只有在主线程才能对ui进行更新操作,而其它线程不能直接对ui进行操作

android本身是一个多线程的操作系统,我们不能把所有的操作都放在主线程中操作 ,比如一些耗时操作。如果放在主线程中 会造成阻塞 而当阻塞事件过长时 系统会抛出anr异常。所以我们要使用异步任务。android为我们提供了一个封装好的组件asynctask。

AsyncTask可以在子线程中更新ui,封装简化了异步操作。适用于简单的异步处理。如果多个后台任务时就要使用Handler了 在这里就不再说明。

AsyncTask通常用于被继承。AsyncTask定义了三种泛型类型<Params,Progress,Result>

Params:启动任务时输入的参数类型

Progress:后台任务执行的百分比

Result:执行任务完成后返回结果的类型

继承AsyncTask后要重写的方法有:

doInBackgroud:必须重写,异步执行后台线程要完成的任务,耗时任务要写在这里,并且在这里不能操作ui。可以调用 publishProgress方法来更新实时的任务进度

onPreExecute:执行耗时操作前调用,可以完成一些初始化操作

onPostExecute:在doInBackground 执行完成后,主线程调用此方法,可以在此方法中操作ui

onProgressUpdate:在doInBackgroud方法中调用publishProgress方法,更新任务的执行进度后 就会调用这个方法

下面通过一个实例来了解AsyncTask

首先附上运行结果


布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <Button        android:id="@+id/btn_download"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal"        android:text="点击下载" />    <FrameLayout        android:layout_width="fill_parent"        android:layout_height="fill_parent" >        <ImageView            android:id="@+id/iv_image"            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:scaleType="fitCenter" />    </FrameLayout></LinearLayout>
MainActivity

package com.example.asynctask;import java.io.BufferedInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.MalformedURLException;import java.net.URLConnection;import android.os.AsyncTask;import android.os.Bundle;import android.app.Activity;import android.app.ProgressDialog;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;public class MainActivity extends Activity implements OnClickListener{private ImageView image;private ProgressDialog progress;private Button btn_download;private static String URL="http://img4.imgtn.bdimg.com/it/u=1256159061,743487979&fm=21&gp=0.jpg";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);image=(ImageView) findViewById(R.id.iv_image);btn_download=(Button) findViewById(R.id.btn_download);progress=new ProgressDialog(this);progress.setIcon(R.drawable.ic_launcher);progress.setTitle("提示信息");progress.setMessage("正在下载,请稍候...");progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);btn_download.setOnClickListener(this);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubnew MyAsyncTask().execute(URL);}/* * String*********对应我们的URL类型 * Integer********进度条的进度值 * BitMap*********异步任务完成后返回的类型   * */class MyAsyncTask extends AsyncTask<String, Integer, Bitmap>{//执行异步任务(doInBackground)之前执行,并且在ui线程中执行@Overrideprotected void onPreExecute() {// TODO Auto-generated method stubsuper.onPreExecute();if(image!=null){image.setVisibility(View.GONE);}//开始下载 对话框进度条显示progress.show();progress.setProgress(0);}@Overrideprotected Bitmap doInBackground(String... params) {// TODO Auto-generated method stub//params是一个可变长的数组 在这里我们只传进来了一个url String url=params[0];Bitmap bitmap=null;URLConnection connection;InputStream is;//用于获取数据的输入流ByteArrayOutputStream bos;//可以捕获内存缓冲区的数据,转换成字节数组。int len;float count=0,total;//count为图片已经下载的大小 total为总大小try {//获取网络连接对象connection=(URLConnection) new java.net.URL(url).openConnection();//获取当前页面的总长度total=(int)connection.getContentLength();//获取输入流is=connection.getInputStream();bos=new ByteArrayOutputStream();byte []data=new byte[1024];while((len=is.read(data))!=-1){count+=len;bos.write(data,0,len);//调用publishProgress公布进度,最后onProgressUpdate方法将被执行publishProgress((int)(count/total*100));//为了显示出进度 人为休眠0.5秒Thread.sleep(500);}bitmap=BitmapFactory.decodeByteArray(bos.toByteArray(), 0, bos.toByteArray().length);is.close();bos.close();} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}return bitmap;}//在ui线程中执行 可以操作ui@Overrideprotected void onPostExecute(Bitmap bitmap) {// TODO Auto-generated method stubsuper.onPostExecute(bitmap);//下载完成 对话框进度条隐藏progress.cancel();image.setImageBitmap(bitmap);image.setVisibility(View.VISIBLE);}/* * 在doInBackground方法中已经调用publishProgress方法 更新任务的执行进度后 * 调用这个方法 实现进度条的更新 * */@Overrideprotected void onProgressUpdate(Integer... values) {// TODO Auto-generated method stubsuper.onProgressUpdate(values);progress.setProgress(values[0]);}}}

最后不要忘记在AndroidManifest文件中配置网络访问权限

<uses-permission android:name="android.permission.INTERNET"/>


更多相关文章

  1. Android中的文件读写操作
  2. android 程序开发的插件化 模块化方法
  3. android studio 3.x 以上版本的Native JNI/NDK 调用c++/c语言程
  4. Android WebView 不支持 H5 input type="file" 解决方法
  5. 在Android App开发中实现任意Java方法的拦截
  6. 关于Android长按出现复制粘贴栏在顶部占位问题解决方法
  7. Android中常用的位图操作(View与Bitmap转化、圆角、灰化、提取Alp
  8. Android进程保活方法 --转自腾讯Bugly公众号
  9. android用ClipDrawable自定义各种进度条(包括竖直和水平)

随机推荐

  1. android 4.0 home
  2. Android(安卓)HttpURLConnection Post请
  3. Ubuntu 下开发 Android 环境变量设置
  4. Android中Dialog实现自定义弹出对话框
  5. Android按钮设置文字变色
  6. android启动:app_process实现恢复出厂设置
  7. Android自定义对话框
  8. Android Log Analysis bugreport
  9. Android sqlite3 数据库批量操作
  10. Android跟踪NDK崩溃信息