今天介绍第二种异步更新界面的方式:AsyncTask
官方文档:
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
AsyncTask能够更恰当和更简单的去使用UI线程。这个类允许执行后台操作和展现结果在UI线程上,无需操纵线程和/或处理程序。AsyncTask的内部实现是一个线程池,每个后台任务会提交到线程池中的线程执行,然后使用Thread+Handler的方式调用回调函数。
1.AsyncTask抽象出后台线程运行的五个状态:
分别是:1、准备运行,2、正在后台运行,3、进度更新,4、完成后台任务,5、取消任务,对于这五个阶段,AsyncTask提供了五个回调函数:
1、准备运行:onPreExecute(),该回调函数在任务被执行之后立即由UI线程调用。这个步骤通常用来建立任务,在用户接口(UI)上显示进度条。
2、正在后台运行:doInParams...),该回调函数由后台线程在onPreExecute()方法执行结束后立即调用。通常在这里执行耗时的后台计算。计算的结果必须由该函数返回,并被传递到onPostExecute()中。在该函数内也可以使用publishProgress(Progress...)来发布一个或多个进度单位(unitsof progress)。这些值将会在onProgressUpdate(Progress...)中被发布到UI线程。
3. 进度更新:onProgressUpdate(Progress...),该函数由UI线程在publishProgress(Progress...)方法调用完后被调用。一般用于动态地显示一个进度条。
4. 完成后台任务:onPostExecute(Result),当后台计算结束后调用。后台计算的结果会被作为参数传递给这一函数。
5、取消任务:onCancelled (),在调用AsyncTask的cancel()方法时调用
2.使用:
AsyncTask必须使用子类。子类会覆盖至少一个方法(doInParams…)),通常将覆盖第二个(onPostExecute(结果)。< /span>
1.Params,传递给后台任务的参数类型。
2.Progress,后台计算执行过程中,进步单位(progress units)的类型。(就是后台程序已经执行了百分之几了。)
3.Result, 后台执行返回的结果的类型。
AsyncTask并不总是需要使用上面的全部3种类型。标识不使用的类型很简单,只需要使用Void类型即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<code>import</code> <code>java.io.InputStream;</code>
<code>import</code> <code>java.net.HttpURLConnection;</code>
<code>import</code> <code>java.net.URL;</code>
<code>import</code> <code>android.app.Activity;</code>
<code>import</code> <code>android.graphics.Bitmap;</code>
<code>import</code> <code>android.graphics.BitmapFactory;</code>
<code>import</code> <code>android.os.AsyncTask;</code>
<code>import</code> <code>android.os.Bundle;</code>
<code>import</code> <code>android.view.View;</code>
<code>import</code> <code>android.view.View.OnClickListener;</code>
<code>import</code> <code>android.widget.Button;</code>
<code>import</code> <code>android.widget.ImageView;</code>
<code>import</code> <code>android.widget.ProgressBar;</code>
<code>import</code> <code>android.widget.Toast;</code>
<code>/**</code>
<code> </code><code>* AsyncTask 实现异步加载图片</code>
<code> </code><code>* @author ZHF</code>
<code> </code><code>*</code>
<code> </code><code>*/</code>
<code>public</code> <code>class</code> <code>MainActivity </code><code>extends</code> <code>Activity {</code>
<code> </code>
<code> </code><code>public</code> <code>static</code> <code>final</code> <code>String IMG_URL=</code><code>"http://images.51cto.com/images/index/Images/Logo.gif"</code><code>;</code>
<code> </code><code>Button btn_asynctask;</code>
<code> </code><code>ImageView imgView;</code>
<code> </code><code>ProgressBar progressBar;</code>
<code> </code><code>@Override</code>
<code> </code><code>protected</code> <code>void</code> <code>onCreate(Bundle savedInstanceState) {</code>
<code> </code><code>super</code><code>.onCreate(savedInstanceState);</code>
<code> </code><code>setContentView(R.layout.activity_main);</code>
<code> </code><code>//加载控件</code>
<code> </code><code>imgView = (ImageView) </code><code>this</code><code>.findViewById(R.id.imageView);</code>
<code> </code><code>btn_asynctask = (Button) </code><code>this</code><code>.findViewById(R.id.btn_AsyncTask);</code>
<code> </code><code>progressBar = (ProgressBar) </code><code>this</code><code>.findViewById(R.id.progressBar);</code>
<code> </code><code>//绑定监听器</code>
<code> </code><code>btn_asynctask.setOnClickListener(</code><code>new</code> <code>OnClickListener() {</code>
<code> </code><code>@Override</code>
<code> </code><code>public</code> <code>void</code> <code>onClick(View v) {</code>
<code> </code><code>GetImgTask getImgTask = </code><code>new</code> <code>GetImgTask();</code>
<code> </code><code>getImgTask.execute(IMG_URL); </code><code>//执行该任务</code>
<code> </code><code>}</code>
<code> </code><code>});</code>
<code> </code><code>}</code>
<code> </code><code>/**获取网络图片任务**/</code>
<code> </code><code>private</code> <code>class</code> <code>GetImgTask </code><code>extends</code> <code>AsyncTask<String, Integer, Bitmap> {</code>
<code> </code>
<code> </code><code>/**在 doInParams...)之前被调用,在ui线程执行 **/</code>
<code> </code><code>@Override</code>
<code> </code><code>protected</code> <code>void</code> <code>onPreExecute() {</code>
<code> </code><code>imgView.setImageBitmap(</code><code>null</code><code>);</code>
<code> </code><code>progressBar.setProgress(</code><code>0</code><code>); </code><code>//进度条复位</code>
<code> </code><code>}</code>
<code> </code><code>/**在后台线程中执行的任务**/</code>
<code> </code><code>protected</code> <code>Bitmap doInString... params) {</code>
<code> </code>
<code> </code><code>publishProgress(</code><code>0</code><code>); </code><code>//会调用onProgressUpdate更新界面</code>
<code> </code><code>InputStream inputStream = </code><code>null</code><code>;</code>
<code> </code><code>Bitmap imgBitmap = </code><code>null</code><code>;</code>
<code> </code><code>try</code> <code>{</code>
<code> </code><code>URL url = </code><code>new</code> <code>URL(IMG_URL);</code>
<code> </code><code>if</code><code>(url != </code><code>null</code><code>) {</code>
<code> </code><code>HttpURLConnection connection = (HttpURLConnection) url.openConnection();</code>
<code> </code><code>connection.setConnectTimeout(</code><code>2000</code><code>);</code>
<code> </code><code>connection.setDoInput(</code><code>true</code><code>);</code>
<code> </code><code>connection.setRequestMethod(</code><code>"GET"</code><code>);</code>
<code> </code><code>int</code> <code>code = connection.getResponseCode();</code>
<code> </code><code>if</code><code>(</code><code>200</code> <code>== code) {</code>
<code> </code><code>inputStream = connection.getInputStream();</code>
<code> </code><code>imgBitmap = BitmapFactory.decodeStream(inputStream);</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code> </code><code>} </code><code>catch</code> <code>(Exception e) {</code>
<code> </code><code>e.printStackTrace();</code>
<code> </code><code>return</code> <code>null</code><code>;</code>
<code> </code><code>publishProgress(</code><code>100</code><code>); </code><code>//下载完成,更新进度条为满格</code>
<code> </code><code>//这里不是UI线程,故不能直接setImage(imgBitmap),</code>
<code> </code><code>return</code> <code>imgBitmap;</code>
<code> </code><code>/**在调用publishProgress之后被调用,在ui线程执行 **/</code>
<code> </code><code>protected</code> <code>void</code> <code>onProgressUpdate(Integer... values) {</code>
<code> </code><code>progressBar.setProgress(values[</code><code>0</code><code>]); </code><code>//设置进度条的进度</code>
<code> </code><code>/**在后台线程执行完成之后,调用该方法,获取数据更新界面**/</code>
<code> </code><code>protected</code> <code>void</code> <code>onPostExecute(Bitmap result) {</code>
<code> </code><code>if</code><code>(result != </code><code>null</code><code>) {</code>
<code> </code><code>Toast.makeText(MainActivity.</code><code>this</code><code>, </code><code>"成功获取图片"</code><code>, Toast.LENGTH_LONG).show();</code>
<code> </code><code>imgView.setImageBitmap(result);</code>
<code> </code><code>}</code><code>else</code> <code>{</code>
<code> </code><code>Toast.makeText(MainActivity.</code><code>this</code><code>, </code><code>"获取图片失败"</code><code>, Toast.LENGTH_LONG).show();</code>
<code> </code><code>/**取消任务,在ui线程执行 **/</code>
<code> </code><code>protected</code> <code>void</code> <code>onCancelled() {</code>
<code> </code><code>progressBar.setProgress(</code><code>0</code><code>);</code><code>//进度条复位</code>
<code> </code><code>super</code><code>.onCancelled();</code>
<code>}</code>
分析:
1.点击按钮之后,创建一个任务,参数值为url(所以第一个参数为String)
2.UI线程执行onPreExecute(),把ImageView的图片清空,progrssbar的进度清零。
3.后台线程执行doInBackground(),不可以在doInBackground()操作ui,调用publishProgress(0)更新进度,此时会调用onProgressUpdate(Integer...progress)更新进度条(进度用整形表示,因此AsyncTask的第二个模板参数是Integer)。函数最后返回result(例子中是返回Bitmap类型,因此AsyncTask的第三个模板参数是Bitmap)。
4.当后台任务执行完成后,调用onPostExecute(Result),传入的参数是doInBackground()中返回的对象。
参考博客:http://blog.csdn.net/mylzc/article/details/6772129
源码下载请看附件
<a href="http://down.51cto.com/data/2363166" target="_blank">附件:http://down.51cto.com/data/2363166</a>
本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1252156,如需转载请自行联系原作者