Android中后台线程如何与UI线程交互

我想关于这个话题已经有很多前辈讨论过了。今天算是一次学习总结吧。

在android的设计思想中,为了确保用户顺滑的操作体验。一些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务。因此我们必须要重新开启一个后台线程运行这些任务。然而,往往这些任务最终又会直接或者间接的需要访问和控制UI控件。例如访问网络获取数据,然后需要将这些数据处理显示出来。就出现了上面所说的情况。原本这是在正常不过的现象了,但是android规定除了UI线程外,其他线程都不可以对那些UI控件访问和操控。为了解决这个问题,于是就引出了我们今天的话题。Android中后台线程如何与UI线程交互。

 

据我所知android提供了以下几种方法,用于实现后台线程与UI线程的交互。

1、handler

2、Activity.runOnUIThread(Runnable)

3、View.Post(Runnable)

4、View.PostDelayed(Runnabe,long)

5、AsyncTask

 

方法一:handler

handler是android中专门用来在线程之间传递信息类的工具。

要讲明handler的用法非常简单,但是我在这里会少许深入的讲一下handler的运行机制。

为了能够让handler在线程间传递消息,我们还需要用到几个类。他们是looper,messageQueue,message。

这里说的looper可不是前段时间的好莱坞大片环形使者,他的主要功能是为特定单一线程运行一个消息环。一个线程对应一个looper。同样一个looper对应一个线程。这就是所谓的特定单一。一般情况下,在一个线程创建时他本身是不会生产他特定单一的looper的(主线程是个特例)。因此我们需要手动的把一个looper与线程相关联。其方法只需在需要关联的looper的线程中调用Looper.prepare。之后我们再调用Looper.loop启动looper。

说了这么多looper的事情,到底这个looper有什么用哪。其实之前我们已经说到了,他是为线程运行一个消息环。具体的说,在我们将特定单一looper与线程关联的时候,looper会同时生产一个messageQueue。他是一个消息队列,looper会不停的从messageQuee中取出消息,也就是message。然后线程就会根据message中的内容进行相应的操作。

那么messageQueue中的message是从哪里来的哪?那就要提到handler了。在我们创建handler的时候,我们需要与特定的looper绑定。这样通过handler我们就可以把message传递给特定的looper,继而传递给特定的线程。在这里,looper和handler并非一一对应的。一个looper可以对应多个handler,而一个handler只能对应一个looper(突然想起了一夫多妻制,呵呵)。这里补充一下,handler和looper的绑定,是在构建handler的时候实现的,具体查询handler的构造函数。

在我们创建handler并与相应looper绑定之后,我们就可以传递message了。我们只需要调用handler的sendMessage函数,将message作为参数传递给相应线程。之后这个message就会被塞进looper的messageQueue。然后再被looper取出来交给线程处理。

这里要补充说一下message,虽然我们可以自己创建一个新的message,但是更加推荐的是调用handler的obtainMessage方法来获取一个message。这个方法的作用是从系统的消息池中取出一个message,这样就可以避免message创建和销毁带来的资源浪费了(这也就是算得上重复利用的绿色之举了吧)。

突然发现有一点很重要的地方没有讲到,那就是线程从looper收到message之后他是如何做出响应的嘞。其实原来线程所需要做出何种响应需要我们在我们自定义的handler类中的handleMessage重构方法中编写。之后才是之前说的创建handler并绑定looper。

好吧说的可能哟点乱,总结一下利用handler传递信息的方法。

假设A线程要传递信息给B线程,我们需要做的就是

1、在B线程中调用Looper.prepare和Looper.loop。(主线程不需要)

2、 编写Handler类,重写其中的handleMessage方法。

3、创建Handler类的实例,并绑定looper

4、调用handler的sentMessage方法发送消息。

到这里,我们想handler的运行机制我应该是阐述的差不多了吧,最后再附上一段代码,供大家参考。

复制代码
 1 public class MyHandlerActivity extends Activity {
 2      TextView textView;
 3      MyHandler myHandler;
 4  
 5      protected void onCreate(Bundle savedInstanceState) {
 6          super.onCreate(savedInstanceState);
 7          setContentView(R.layout.handlertest);
 8  
 9          //实现创建handler并与looper绑定。这里没有涉及looper与
//线程的关联是因为主线程在创建之初就已有looper
10 myHandler=MyHandler(MyHandlerActivitythis.getMainLooper()); 11 textView = (textView) findViewById(R.id.textView); 12 13 MyThread m = new MyThread(); 14 new Thread(m).start(); 15 } 16 17 18 class MyHandler extends Handler { 19 public MyHandler() { 20 } 21 22 public MyHandler(Looper L) { 23 super(L); 24 } 25 26 // 必须重写这个方法,用于处理message 27 @Override 28 public void handleMessage(Message msg) { 29 // 这里用于更新UI 30 Bundle b = msg.getData(); 31 String color = b.getString("color"); 32 MyHandlerActivity.this.textView.setText(color); 33 } 34 } 35 36 class MyThread implements Runnable { 37 public void run() { 38 //从消息池中取出一个message 39 Message msg = myHandler.obtainMessage(); 40 //Bundle是message中的数据 41 Bundle b = new Bundle(); 42 b.putString("color", "我的"); 43 msg.setData(b); 44 //传递数据 45 myHandler.sendMessage(msg); // 向Handler发送消息,更新UI 46 } 47 }
复制代码

 

参考资料:

http://developer.android.com/reference/android/os/Handler.html

http://developer.android.com/reference/android/os/Looper.html

http://developer.android.com/reference/android/os/Message.html

http://www.cnblogs.com/dawei/archive/2011/04/09/2010259.html

http://rxwen.blogspot.com/2010/08/looper-and-handler-in-android.html

http://www.cnblogs.com/android007/archive/2012/05/10/2494766.html

 

方法二:Activity.runOnUIThread(Runnable)

 这个方法相当简单,我们要做的只是以下几步

1、编写后台线程,这回你可以直接调用UI控件

2、创建后台线程的实例

3、调用UI线程对应的Activity的runOnUIThread方法,将后台线程实例作为参数传入其中。

注意:无需调用后台线程的start方法

方法三:View.Post(Runnable)

 该方法和方法二基本相同,只是在后台线程中能操控的UI控件被限制了,只能是指定的UI控件View。方法如下

1、编写后台线程,这回你可以直接调用UI控件,但是该UI控件只能是View

2、创建后台线程的实例

3、调用UI控件View的post方法,将后台线程实例作为参数传入其中。

方法四:View.PostDelayed(Runnabe,long)

该方法是方法三的补充,long参数用于制定多少时间后运行后台进程 

方法五:AsyncTask

AsyncTask是一个专门用来处理后台进程与UI线程的工具。通过AsyncTask,我们可以非常方便的进行后台线程和UI线程之间的交流。

那么AsyncTask是如何工作的哪。

AsyncTask拥有3个重要参数

1、Params 

2、Progress

3、Result

Params是后台线程所需的参数。在后台线程进行作业的时候,他需要外界为其提供必要的参数,就好像是一个用于下载图片的后台进程,他需要的参数就是图片的下载地址。

Progress是后台线程处理作业的进度。依旧上面的例子说,就是下载图片这个任务完成了多少,是20%还是60%。这个数字是由Progress提供。

Result是后台线程运行的结果,也就是需要提交给UI线程的信息。按照上面的例子来说,就是下载完成的图片。

AsyncTask还拥有4个重要的回调方法。

1、onPreExecute

2、doInBackground

3、onProgressUpdate

4、onPostExecute

onPreExecute运行在UI线程,主要目的是为后台线程的运行做准备。当他运行完成后,他会调用doInBackground方法。

doInBackground运行在后台线程,他用来负责运行任务。他拥有参数Params,并且返回Result。在后台线程的运行当中,为了能够更新作业完成的进度,需要在doInbackground方法中调用PublishProgress方法。该方法拥有参数Progress。通过该方法可以更新Progress的数据。然后当调用完PublishProgress方法,他会调用onProgressUpdate方法用于更新进度。

onProgressUpdate运行在UI线程,主要目的是用来更新UI线程中显示进度的UI控件。他拥有Progress参数。在doInBackground中调用PublishProgress之后,就会自动调onProgressUpdate方法

onPostExecute运行在UI线程,当doInBackground方法运行完后,他会调用onPostExecute方法,并传入Result。在onPostExecute方法中,就可以将Result更新到UI控件上。

明白了上面的3个参数和4个方法,你要做的就是

1、编写一个继承AsyncTask的类,并声明3个参数的类型,编写4个回调方法的内容。

2、然后在UI线程中创建该类(必须在UI线程中创建)。

3、最后调用AsyncTask的execute方法,传入Parmas参数(同样必须在UI线程中调用)。

这样就大功告成了。

另外值得注意的2点就是,千万不要直接调用那四个回调方法。还有就是一个AsyncTask实例只能执行一次,否则就出错哦。

以上是AsyncTask的基本用法,更加详细的内容请参考android官方文档。最后附上一段代码,供大家参考。

 

复制代码
 1 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> 
 2 //在这里声明了Params、Progress、Result参数的类型
 3 {
 4     //因为这里不需要使用onPreExecute回调方法,所以就没有加入该方法
 5     
 6     //后台线程的目的是更具URL下载数据
 7      protected Long doInBackground(URL... urls) {
 8          int count = urls.length;//urls是数组,不止一个下载链接
 9          long totalSize = 0;//下载的数据
10          for (int i = 0; i < count; i++) {
11              //Download是用于下载的一个类,和AsyncTask无关,大家可以忽略他的实现
12              totalSize += Downloader.downloadFile(urls[i]);
13              publishProgress((int) ((i / (float) count) * 100));//更新下载的进度
14              // Escape early if cancel() is called
15              if (isCancelled()) break;
16          }
17          return totalSize;
18      }
19 
20      //更新下载进度
21      protected void onProgressUpdate(Integer... progress) {
22          setProgressPercent(progress[0]);
23      }
24 
25      //将下载的数据更新到UI线程
26      protected void onPostExecute(Long result) {
27          showDialog("Downloaded " + result + " bytes");
28      }
29  }
30  
复制代码

 

 

 

 有了上面的这个类,接下你要做的就是在UI线程中创建实例,并调用execute方法,传入URl参数就可以了。

 参考资料
http://developer.android.com/reference/android/os/AsyncTask.html
http://www.cnblogs.com/dawei/archive/2011/04/18/2019903.html

 

这上面的5种方法各有优点。但是究其根本,其实后面四种方法都是基于handler方法的包装。在一般的情形下后面四种似乎更值得推荐。但是当情形比较复杂,还是推荐使用handler。


================================================================================================================

AsyncTask 是 Android 提供的一种异步任务处理类,它与线程类 Thread 相比,有以下优势:

1.preExcute() & postExcute()方法不仅可以进行预处理 & 收尾工作,而且它们归属于 UI 线程,所以你可以进行开启、关闭 loading 对话框等操作。

2.doInBackground()方法 & 构造器都支持泛型参数,且内部可以进行参数传递,封装性较好,注意doInBackground()属于后台线程,不能执行 UI 操作。

3.AsyncTask 比 Thread 更容易控制,它提供了cancel()方法,关于AsyncTask生命周期,

一、定义

  1. private class MyAsyncTask extern AsyncTask{  
  2. ...  
  3. }  

二、实例化 & 执行

  1. MyAsyncTask task = new MyAsyncTask();  
  2. task.excute();  

三、AsyncTask 的生命周期
AsyncTask 会依次执行 onPreExcute()—doInBackground()—[可能执行onCancel()]—onPostExcute().

四、注意事项:
1.AsyncTask 的最大上限数量
我没有在SDK的文档中找到具体说明,但开发中已经领教过了,同种类型的 AsyncTask 实例,最大数量为 20 个。
如果超过,则会引发 RejectExcuteException,并 crash
因此,要考虑到用户的操作是否会引发频繁的 AsyncTask 实例化,若存在,则从 UI 上进行改进,比如:
分页机制;
线程池;
生产者-消费者模型。

2.取消AsyncTask任务
文档已经说明,cancel()方法不一定能成功,所以 onCancel() 回调方法不一定被调用。
但若一个 AsyncTask 结束,则一定会调用 onPostExcute() 方法。
对于一个 doInBackground()方法中含有 while/for 循环时,最好配置 isCancel标置来 break 循环。


================================================================================================================

  * Params 启动任务执行的输入参数,比如HTTP请求的URL。
    * Progress 后台任务执行的百分比。
    * Result 后台执行任务最终返回的结果,比如String。

      AsyncTask 的执行分为四个步骤,与前面定义的TaskListener类似。每一步都对应一个回调方法,需要注意的是这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。在任务的执行过程中,这些方法被自动调用。

    * onPreExecute() 当任务执行之前开始调用此方法,可以在这里显示进度对话框。
    * doInBackground(Params...) 此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress...)来更新任务的进度。
    * onProgressUpdate(Progress...) 此方法在主线程执行,用于显示任务执行的进度。
    * onPostExecute(Result) 此方法在主线程执行,任务执行的结果作为此方法的参数返回。

      PageTask扩展了AsyncTask,在 doInBackground()方法中读取网页内容。PageTask的源代码如下所示:

  1. // 设置三种类型参数分别为String,Integer,String  
  2.     class PageTask extends AsyncTask<String, Integer, String> {  
  3.   
  4.         // 可变长的输入参数,与AsyncTask.exucute()对应  
  5.         @Override  
  6.         protected String doInBackground(String... params) {  
  7.             try {  
  8.                 HttpClient client = new DefaultHttpClient();  
  9.                 // params[0] 代表连接的url  
  10.                 HttpGet get = new HttpGet(params[0]);  
  11.                 HttpResponse response = client.execute(get);  
  12.                 HttpEntity entity = response.getEntity();  
  13.                 long length = entity.getContentLength();  
  14.                 InputStream is = entity.getContent();  
  15.                 String s = null;  
  16.                 if (is != null) {  
  17.                     ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  18.                     byte[] buf = new byte[128];  
  19.                     int ch = -1;  
  20.                     int count = 0;  
  21.                     while ((ch = is.read(buf)) != -1) {  
  22.                         baos.write(buf, 0, ch);  
  23.                         count += ch;  
  24.                         if (length > 0) {  
  25.                             // 如果知道响应的长度,调用publishProgress()更新进度  
  26.                             publishProgress((int) ((count / (float) length) * 100));  
  27.                         }  
  28.                         // 为了在模拟器中清楚地看到进度,让线程休眠100ms  
  29.                         Thread.sleep(100);  
  30.                     }  
  31.                     s = new String(baos.toByteArray());            }  
  32.                 // 返回结果  
  33.                 return s;  
  34.             } catch (Exception e) {  
  35.                 e.printStackTrace();  
  36.             }  
  37.             return null;  
  38.         }  
  39.         @Override  
  40.         protected void onCancelled() {  
  41.             super.onCancelled();  
  42.         }  
  43.         @Override  
  44.         protected void onPostExecute(String result) {  
  45.             // 返回HTML页面的内容  
  46.             message.setText(result);  
  47.         }  
  48.         @Override  
  49.         protected void onPreExecute() {  
  50.             // 任务启动,可以在这里显示一个对话框,这里简单处理  
  51.             message.setText(R.string.task_started);  
  52.         }  
  53.         @Override  
  54.         protected void onProgressUpdate(Integer... values) {  
  55.             // 更新进度  
  56.             message.setText(values[0]);  
  57.         }  
  58.     }
复制代码
执行PageTask非常简单,只需要调用如下代码。重新运行NetworkActivity,不但可以抓取网页的内容,还可以实时更新读取的进度。读者尝试读取一个较大的网页,看看百分比的更新情况。
  1. PageTask task = new PageTask();  
  2. task.execute(url.getText().toString());

================================================================================================================

   
   
  1. import android.app.Activity; 
  2. import android.os.AsyncTask; 
  3. import android.os.Bundle; 
  4. import android.view.View; 
  5. import android.view.View.OnClickListener; 
  6. import android.widget.Button; 
  7. import android.widget.ProgressBar; 
  8. import android.widget.TextView; 
  9.   
  10. public class AsyncTaskDemoActivity extends Activity { 
  11.        private ProgressBar bar = null
  12.        private Button start = null 
  13.        private TextView percent = null 
  14.     /** Called when the activity is first created. */ 
  15.  
  16.     @Override 
  17.     public void onCreate(Bundle savedInstanceState) { 
  18.  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.main);  
  21.         
  22.         start = (Button)findViewById(R.id.start); //Start按钮 
  23.         
  24.         start.setOnClickListener(new OnClickListener() { 
  25.  
  26.                      @Override 
  27.                      public void onClick(View arg0) { 
  28.                             // TODO Auto-generated method stub  
  29.                             SubAsyncTask sat = new SubAsyncTask(); //创建AsyncTask子类的实例 
  30.                             sat.execute(); //启动线程
  31.                      } 
  32.               });         
  33.     } 
  34.     
  35.     public class SubAsyncTask extends AsyncTask<Object, Integer, String>{ 
  36.  
  37.   
  38.     @Override 
  39.     protected void onPreExecute() { 
  40.             // TODO Auto-generated method stub 
  41.             System.out.println("Thread in onPreExecute---->"+Thread.currentThread().getName()); 
  42.   //在预处理方法中定义进度条和百分比文本
  43.             bar = (ProgressBar)findViewById(R.id.bar); 
  44.             bar.setVisibility(View.VISIBLE);
  45.  
  46.             percent = (TextView)findViewById(R.id.percent);  
  47.             percent.setVisibility(View.VISIBLE); 
  48.             super.onPreExecute(); 
  49.     } 
  50.     
  51.     @Override 
  52.     protected String doInBackground(Object... arg0) { 
  53.  
  54.             // TODO Auto-generated method stub 
  55.             //每50ms执行一次publishProgress
  56.             for (int j = 0; j <=100; j+=10) { 
  57.                    System.out.println("Thread in doInBackground---->"+Thread.currentThread().getName()); 
  58.  
  59.                    publishProgress(j); 
  60.                    try { 
  61.                           Thread.sleep(50); 
  62.                    } catch (InterruptedException e) { 
  63.  
  64.                           // TODO Auto-generated catch block 
  65.  
  66.                           e.printStackTrace(); 
  67.                    } 
  68.             } 
  69.             return null
  70.     } 
  71.     
  72.     @Override 
  73.     protected void onProgressUpdate(Integer... values) { 
  74.  
  75.             // TODO Auto-generated method stub 
  76. //每执行一次publishProgress就需要执行一次这个函数,在这个函数里变化进度条信息
  77.             System.out.println("Thread in onProgressUpdate---->"+Thread.currentThread().getName()); 
  78.  
  79.             bar.setProgress(values[0]); 
  80.             percent.setText(values[0]+"%"); 
  81.     } 
  82.     
  83.     @Override 
  84.     protected void onPostExecute(String result) { 
  85.             // TODO Auto-generated method stub 
  86. //doInBackground方法执行完后,执行这个函数,用来提交结果
  87.             bar.setVisibility(View.GONE); 
  88.             percent.setVisibility(View.GONE); 
  89.             System.out.println("Thread in onPostExecute---->"+Thread.currentThread().getName()); 
  90.  
  91.             super.onPostExecute(result); 
  92.     } 
  93.     } 
从代码看出,我们并没有将 UI上得进度条控件和文本控件在onCreate函数中创建,而是只创建了一个开始Button,然后用匿名内部类为该Button绑定了一个事件监听器。在监听器内部,我们实例化了SubAsyncTask,SubAsyncTask是AsyncTask的子类,然后调用execute()方法来启动它。
 
重要的我们看 SubAsyncTask子类的实现。它继承了AsyncTask类并且重载了四个方法,也就是上面我提到的那四个方法。窝在每个方法内都设置了输出语句,查看当前的方法是哪个线程在执行。
作为预处理方法,我在 onPreExecute()方法中定义了进度条和百分比的TextView。当该函数执行完毕后,就开始执行doInBackground方法,在此方法中,我每隔50ms就执行一次publishProgress方法,这就意味着相应的,会有一个onProgressUpdate方法被调用,在onProgressUpdate方法中,我对进度条和进度百分比进行改变设置。当doInBackground方法运行完毕后,会自动执行onPostExecute方法,来提交执行的结果。
下图为运行的效果图:

 
================================================================================================================================
再举一个例子:
main.xml
[java]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7.     <TextView    
  8.     android:id="@+id/textView01"  
  9.     android:layout_width="fill_parent"   
  10.     android:layout_height="wrap_content"   
  11.     />  
  12.    <ProgressBar   
  13.    android:id="@+id/progressBar02"  
  14.     android:layout_width="fill_parent"   
  15.     android:layout_height="wrap_content"   
  16.     style="?android:attr/progressBarStyleHorizontal"   
  17.     />  
  18.     <Button  
  19.     android:id="@+id/button03"  
  20.     android:layout_width="fill_parent"   
  21.     android:layout_height="wrap_content"   
  22.     android:text="更新progressbar"  
  23.     />  
  24. </LinearLayout>  


MainActivity.java

[html]  view plain copy
  1. package vic.wong.main;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.View;  
  6. import android.view.View.OnClickListener;  
  7. import android.widget.Button;  
  8. import android.widget.ProgressBar;  
  9. import android.widget.TextView;  
  10.   
  11. public class MainActivity extends Activity {  
  12.     private Button button;  
  13.     private ProgressBar progressBar;  
  14.     private TextView textView;  
  15.       
  16.     @Override  
  17.     public void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.main);  
  20.           
  21.         button = (Button)findViewById(R.id.button03);  
  22.         progressBar = (ProgressBar)findViewById(R.id.progressBar02);  
  23.         textView = (TextView)findViewById(R.id.textView01);  
  24.           
  25.         button.setOnClickListener(new OnClickListener() {  
  26.               
  27.             @Override  
  28.             public void onClick(View v) {  
  29.                 ProgressBarAsyncTask asyncTask = new ProgressBarAsyncTask(textView, progressBar);  
  30.                 asyncTask.execute(1000);  
  31.             }  
  32.         });  
  33.     }  
  34. }  

 


NetOperator.java

[html]  view plain copy
  1. package vic.wong.main;  
  2.   
  3.   
  4. //模拟网络环境  
  5. public class NetOperator {  
  6.       
  7.     public void operator(){  
  8.         try {  
  9.             //休眠1秒  
  10.             Thread.sleep(1000);  
  11.         } catch (InterruptedException e) {  
  12.             // TODO Auto-generated catch block  
  13.             e.printStackTrace();  
  14.         }  
  15.     }  
  16.   
  17. }  

 


ProgressBarAsyncTask .java 

[html]  view plain copy
  1. package vic.wong.main;  
  2. import android.os.AsyncTask;  
  3. import android.widget.ProgressBar;  
  4. import android.widget.TextView;  
  5.   
  6. /**  
  7.  * 生成该类的对象,并调用execute方法之后  
  8.  * 首先执行的是onProExecute方法  
  9.  * 其次执行doInBackgroup方法  
  10.  *  
  11.  */  
  12. public class ProgressBarAsyncTask extends AsyncTask<Integer, Integer, String> {  
  13.   
  14.     private TextView textView;  
  15.     private ProgressBar progressBar;  
  16.       
  17.       
  18.     public ProgressBarAsyncTask(TextView textView, ProgressBar progressBar) {  
  19.         super();  
  20.         this.textView = textView;  
  21.         this.progressBar = progressBar;  
  22.     }  
  23.   
  24.   
  25.     /**  
  26.      * 这里的Integer参数对应AsyncTask中的第一个参数   
  27.      * 这里的String返回值对应AsyncTask的第三个参数  
  28.      * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改  
  29.      * 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作  
  30.      */  
  31.     @Override  
  32.     protected String doInBackground(Integer... params) {  
  33.         NetOperator netOperator = new NetOperator();  
  34.         int i = 0;  
  35.         for (i = 10; i <= 100; i+=10) {  
  36.             netOperator.operator();  
  37.             publishProgress(i);  
  38.         }  
  39.         return i + params[0].intValue() + "";  
  40.     }  
  41.   
  42.   
  43.     /**  
  44.      * 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)  
  45.      * 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置  
  46.      */  
  47.     @Override  
  48.     protected void onPostExecute(String result) {  
  49.         textView.setText("异步操作执行结束" + result);  
  50.     }  
  51.   
  52.   
  53.     //该方法运行在UI线程当中,并且运行在UI线程当中 可以对UI空间进行设置  
  54.     @Override  
  55.     protected void onPreExecute() {  
  56.         textView.setText("开始执行异步线程");  
  57.     }  
  58.   
  59.   
  60.     /**  
  61.      * 这里的Intege参数对应AsyncTask中的第二个参数  
  62.      * 在doInBackground方法当中,,每次调用publishProgress方法都会触发onProgressUpdate执行  
  63.      * onProgressUpdate是在UI线程中执行,所有可以对UI空间进行操作  
  64.      */  
  65.     @Override  
  66.     protected void onProgressUpdate(Integer... values) {  
  67.         int vlaue = values[0];  
  68.         progressBar.setProgress(vlaue);  
  69.     }  
  70.   
  71.       
  72.       
  73.       
  74.   

感谢:http://www.cnblogs.com/qxw1992/archive/2013/02/01/handler-asyncTask-looper-thread-message-android.html

感谢:http://www.oschina.net/question/16_34290

感谢:http://www.pin5i.com/showtopic-android-asynctask-sample.html

感谢:http://www.cnblogs.com/devinzhang/archive/2012/02/13/2350070.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值