使用Android AsyncTask异步线程

本文地址:http://blog.csdn.net/csheng1204/article/details/7233863 转载请注明,谢谢~


首先声明一下,本人是一个只学了几个月Android的新手,如有说得不好,请勿拍砖~~欢迎留言交流。

参考官方文档和老外文章:(需要目田上网)

1Multithreading For Performance

2、Painless threading


另外,关于为什么一开始就讲线程问题,有必要做个说明:

1、Android是单线程UI模型,所以假如不另外开辟线程做一些下载图片、获取网络内容的的操作,会使UI给用户一种“很卡”的感觉;

2、假如不引入多线程,很容易导致Application Not Responding 也就是ANR,应用程序无响应,在手机上面一般表现为弹出一个警告窗口,“强制关闭”、“Force Close”这种恶心的问题;

3、Android本身提供一个封装好的异步线程类叫AsyncTask,为我们管理线程起到很好的作用。

 

AsyncTask<Params, Progress, Result>

用法:

    必须继承AsyncTask并重写至少一个方法 doInBackground(Params...),经常使用的是也重写第二个方法 onPostExecute(Result)

参数:

  1. Params, 开始任务前传入参数,注意的是,可变长输入,可以一次性启动执行多个下载任务,例如传入一组String[];
  2. Progress,在后台任务计算时,向外发布进程的单位,一般是Int或者Double或者其他;
  3. Result,后台任务计算结束后,返回的结果

    注意以上三个参数皆可为空,只需要传入AsyncTask<Void,Void,Void>即可。

 

进程4部曲:(其实还有1个~)

  1. onPreExecute(),在UI线程调用,然后立刻被执行。这个过程一般用来做一些初始化操作,例如显示出一个ProgressBar提示用户任务已经在执行中、例如让启动任务的Button变为Disabled,防止多次执行;
  2. doInBackground(Params...),当onPreExecute()执行完毕,会立刻在后台线程调用。这个过程一般用来做一些比较耗时的操作,如计算PI(当然没人这么无聊吧~)、例如下载网络图片,结果将会传给最后一个过程onPostExecute(Result)。当然为了使你的程序更加友好,可以显示进度,而具体进度如何,就是通过在这个过程调用 publishProgress(Progress...) 来向外(指UI线程)发布进程。
  3. onProgressUpdate(Progress...),当 publishProgress(Progress...)被调用时,会在UI线程调用此方法。一般是用来提示用户进度,例如用在Notification上面显示下载进度条;
  4. onPostExecute(Result),当任务结束时在UI线程调用,传入参数为doInBackground()的结果~~
  5. onCancelled(),在AsyncTask的cancel()方法被调用时触发调用。

以下是一个自己写的Demo,有一个按钮,按钮启动异步任务下载CSDN logo并显示出来

 

<注意:以下属性match_parent须在Android2.2之后才可以支持,效果同Android2.1及之前的fill_parent>

 
AsyncTaskDemoActivity.java
[java] view plain copy print ?
  1. package com.csheng.asynctask;  
  2.   
  3. import java.io.InputStream;  
  4. import java.net.URL;  
  5. import java.net.URLConnection;  
  6.   
  7. import android.app.Activity;  
  8. import android.graphics.Bitmap;  
  9. import android.graphics.BitmapFactory;  
  10. import android.os.AsyncTask;  
  11. import android.os.Bundle;  
  12. import android.view.View;  
  13. import android.view.View.OnClickListener;  
  14. import android.widget.Button;  
  15. import android.widget.ImageView;  
  16.   
  17. public class AsyncTaskDemoActivity extends Activity {  
  18.   
  19.     public static final String TAG = "AsyncTaskDemoActivity";  
  20.   
  21.     private Button downloadBtn = null;  
  22.     private ImageView logoIv = null;  
  23.     /* CSDN logo */  
  24.     private final String LOGO_URL = "http://csdnimg.cn/www/images/csdnindex_logo.gif";  
  25.   
  26.     @Override  
  27.     public void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.main);  
  30.         findViews();  
  31.     }  
  32.   
  33.     private void findViews() {  
  34.         downloadBtn = (Button) findViewById(R.id.downloadBtn);  
  35.         logoIv = (ImageView) findViewById(R.id.logoIv);  
  36.         downloadBtn.setOnClickListener(new OnClickListener() {  
  37.   
  38.             @Override  
  39.             public void onClick(View v) {  
  40.                 new DownloadAsyncTask().execute(LOGO_URL);// 启动匿名任务  
  41.             }  
  42.         });  
  43.     }  
  44.   
  45.     private class DownloadAsyncTask extends AsyncTask<String, Void, Bitmap> {  
  46.   
  47.         @Override  
  48.         protected Bitmap doInBackground(String... params) {  
  49.             final String urlStr = params[0];// 取出execute所传入参数  
  50.             URL url = null;  
  51.             try {  
  52.                 url = new URL(urlStr);  
  53.                 final URLConnection connection = url.openConnection();  
  54.                 final InputStream inputStream = connection.getInputStream();  
  55.                 final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);  
  56.                 if (bitmap != null) {  
  57.                     return bitmap;// 交给onPostExecute()处理  
  58.                 }  
  59.             } catch (Exception e) {  
  60.                 e.printStackTrace();  
  61.             }  
  62.             return null;  
  63.         }  
  64.   
  65.         @Override  
  66.         protected void onPostExecute(Bitmap result) {  
  67.             if (result != null) {  
  68.                 logoIv.setImageBitmap(result);// 取出doInBackground()的计算结果  
  69.             }  
  70.             downloadBtn.setEnabled(true);  
  71.             super.onPostExecute(result);  
  72.         }  
  73.   
  74.         @Override  
  75.         protected void onPreExecute() {  
  76.   
  77.             downloadBtn.setEnabled(false);// 在整个异步下载期间,不允许重新启动下载任务  
  78.             super.onPreExecute();  
  79.         }  
  80.   
  81.     }  
  82. }  

 

main.xml

[html] view plain copy print ?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <Button  
  7.         android:id="@+id/downloadBtn"  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:layout_centerHorizontal="true"  
  11.         android:text="@string/downloadText" />  
  12.   
  13.     <!-- 图片放置于按钮下方 -->  
  14.   
  15.     <ImageView  
  16.         android:id="@+id/logoIv"  
  17.         android:layout_width="wrap_content"  
  18.         android:layout_height="wrap_content"  
  19.         android:layout_below="@+id/downloadBtn"  
  20.         android:layout_centerHorizontal="true"  
  21.         android:contentDescription="@string/contentDescription" />  
  22.   
  23. </RelativeLayout>  

strings.xml
[html] view plain copy print ?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.   
  4.     <string name="app_name">AsyncTaskDemo</string>  
  5.     <string name="downloadText">下载图片</string>  
  6.     <string name="contentDescription">这是一张图片</string>  
  7.     <string name="startDownloadToast">开始下载图片</string>  
  8.     <string name="setImageToast">设置图片资源</string>  
  9.   
  10. </resources>  

 

对了,还有一个Manifest文件,别忘了添加网络权限

AndroidManifest.xml

[html] view plain copy print ?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.csheng.asynctask"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk android:minSdkVersion="8" />  
  8.   
  9.     <uses-permission android:name="android.permission.INTERNET" />  
  10.   
  11.     <application  
  12.         android:icon="@drawable/ic_launcher"  
  13.         android:label="@string/app_name" >  
  14.         <activity  
  15.             android:name=".AsyncTaskDemoActivity"  
  16.             android:label="@string/app_name" >  
  17.             <intent-filter>  
  18.                 <action android:name="android.intent.action.MAIN" />  
  19.   
  20.                 <category android:name="android.intent.category.LAUNCHER" />  
  21.             </intent-filter>  
  22.         </activity>  
  23.     </application>  
  24.   
  25. </manifest>  

 

再来个图片刺激下~~效果如下:

使用Android AsyncTask异步线程_第1张图片

最后,放出资源地址,有兴趣可以去下载个回去看看。

Android异步线程使用Demo


你可能感兴趣的:(使用Android AsyncTask异步线程)