ASyncTask

来源:互联网 发布:mac 雷欧 编辑:程序博客网 时间:2024/05/01 17:03

在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。在单线程模型中始终要记住两条法则: 
1. 不要阻塞UI线程 
2. 确保只在UI线程中访问Android UI工具包 
    当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。 
   比如说从网上获取一个网页,在一个TextView中将其源代码显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得页面源码后,是不能直接在网络操作线程中调用TextView.setText()的.因为其他线程中是不能直接访问主UI线程成员 


android提供了几种在其他线程中访问UI线程的方法。 
Activity.runOnUiThread( Runnable ) 
View.post( Runnable ) 
View.postDelayed( Runnable, long ) 
Hanlder 
这些类或方法同样会使你的代码很复杂很难理解。然而当你需要实现一些很复杂的操作并需要频繁地更新UI时这会变得更糟糕。 

为了解决这个问题,Android 1.5提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单。不需要借助线程和Handler即可实现。 
AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。 
  Params 启动任务执行的输入参数,比如HTTP请求的URL。 
  Progress 后台任务执行的百分比。 
  Result 后台执行任务最终返回的结果,比如String。 

AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。 
  1) 子类化AsyncTask 
  2) 实现AsyncTask中定义的下面一个或几个方法 
     onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。 
    doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。 
    onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。 
    onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread. 

为了正确的使用AsyncTask类,以下是几条必须遵守的准则: 
  1) Task的实例必须在UI thread中创建 
  2) execute方法必须在UI thread中调用 
  3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法 
  4) 该task只能被执行一次,否则多次调用时将会出现异常 


从网上获取一个网页,在一个TextView中将其源代码显示出来 

Java代码 
  1. package test.list;  
  2. import java.io.ByteArrayOutputStream;  
  3. import java.io.InputStream;  
  4. import java.util.ArrayList;  
  5.   
  6. import org.apache.http.HttpEntity;  
  7. import org.apache.http.HttpResponse;  
  8. import org.apache.http.client.HttpClient;  
  9. import org.apache.http.client.methods.HttpGet;  
  10. import org.apache.http.impl.client.DefaultHttpClient;  
  11.   
  12. import android.app.Activity;  
  13. import android.app.ProgressDialog;  
  14. import android.content.Context;  
  15. import android.content.DialogInterface;  
  16. import android.os.AsyncTask;  
  17. import android.os.Bundle;  
  18. import android.os.Handler;  
  19. import android.os.Message;  
  20. import android.view.View;  
  21. import android.widget.Button;  
  22. import android.widget.EditText;  
  23. import android.widget.TextView;  
  24.   
  25. public class NetworkActivity extends Activity{  
  26.     private TextView message;  
  27.     private Button open;  
  28.     private EditText url;  
  29.   
  30.     @Override  
  31.     public void onCreate(Bundle savedInstanceState) {  
  32.        super.onCreate(savedInstanceState);  
  33.        setContentView(R.layout.network);  
  34.        message= (TextView) findViewById(R.id.message);  
  35.        url= (EditText) findViewById(R.id.url);  
  36.        open= (Button) findViewById(R.id.open);  
  37.        open.setOnClickListener(new View.OnClickListener() {  
  38.            public void onClick(View arg0) {  
  39.               connect();  
  40.            }  
  41.        });  
  42.   
  43.     }  
  44.   
  45.     private void connect() {  
  46.         PageTask task = new PageTask(this);  
  47.         task.execute(url.getText().toString());  
  48.     }  
  49.   
  50.   
  51.     class PageTask extends AsyncTask<String, Integer, String> {  
  52.         // 可变长的输入参数,与AsyncTask.exucute()对应  
  53.         ProgressDialog pdialog;  
  54.         public PageTask(Context context){  
  55.             pdialog = new ProgressDialog(context, 0);     
  56.             pdialog.setButton("cancel"new DialogInterface.OnClickListener() {  
  57.              public void onClick(DialogInterface dialog, int i) {  
  58.               dialog.cancel();  
  59.              }  
  60.             });  
  61.             pdialog.setOnCancelListener(new DialogInterface.OnCancelListener() {  
  62.              public void onCancel(DialogInterface dialog) {  
  63.               finish();  
  64.              }  
  65.             });  
  66.             pdialog.setCancelable(true);  
  67.             pdialog.setMax(100);  
  68.             pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);  
  69.             pdialog.show();  
  70.   
  71.   
  72.         }  
  73.         @Override  
  74.         protected String doInBackground(String... params) {  
  75.   
  76.             try{  
  77.   
  78.                HttpClient client = new DefaultHttpClient();  
  79.                // params[0]代表连接的url  
  80.                HttpGet get = new HttpGet(params[0]);  
  81.                HttpResponse response = client.execute(get);  
  82.                HttpEntity entity = response.getEntity();  
  83.                long length = entity.getContentLength();  
  84.                InputStream is = entity.getContent();  
  85.                String s = null;  
  86.                if(is != null) {  
  87.                    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  88.   
  89.                    byte[] buf = new byte[128];  
  90.   
  91.                    int ch = -1;  
  92.   
  93.                    int count = 0;  
  94.   
  95.                    while((ch = is.read(buf)) != -1) {  
  96.   
  97.                       baos.write(buf, 0, ch);  
  98.   
  99.                       count += ch;  
  100.   
  101.                       if(length > 0) {  
  102.                           // 如果知道响应的长度,调用publishProgress()更新进度  
  103.                           publishProgress((int) ((count / (float) length) * 100));  
  104.                       }  
  105.   
  106.                       // 让线程休眠100ms  
  107.                       Thread.sleep(100);  
  108.                    }  
  109.                    s = new String(baos.toByteArray());              }  
  110.                // 返回结果  
  111.                return s;  
  112.             } catch(Exception e) {  
  113.                e.printStackTrace();  
  114.   
  115.             }  
  116.   
  117.             return null;  
  118.   
  119.         }  
  120.   
  121.         @Override  
  122.         protected void onCancelled() {  
  123.             super.onCancelled();  
  124.         }  
  125.   
  126.         @Override  
  127.         protected void onPostExecute(String result) {  
  128.             // 返回HTML页面的内容  
  129.             message.setText(result);  
  130.             pdialog.dismiss();   
  131.         }  
  132.   
  133.         @Override  
  134.         protected void onPreExecute() {  
  135.             // 任务启动,可以在这里显示一个对话框,这里简单处理  
  136.             message.setText(R.string.task_started);  
  137.         }  
  138.   
  139.         @Override  
  140.         protected void onProgressUpdate(Integer... values) {  
  141.             // 更新进度  
  142.               System.out.println(""+values[0]);  
  143.               message.setText(""+values[0]);  
  144.               pdialog.setProgress(values[0]);  
  145.         }  
  146.   
  147.      }  
  148.   
  149. }  

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝脖子偏了怎么办呢 斜颈导致的脸歪怎么办 斜颈手术后脸部还不对称怎么办 宝宝3个月斜颈怎么办 一岁八个月宝宝斜颈怎么办 四个月宝宝有点斜颈怎么办 一岁宝宝有点偏怎么办 6个月宝宝有点斜颈怎么办 四个月宝宝左侧胸锁乳突肌厚怎么办 脖子疼好几天了怎么办 有双下巴怎么办才能瘦掉 胃突然疼的厉害怎么办 手劳损痛的厉害怎么办 手臂扭到了很疼怎么办 寒湿导致肩膀痛怎么办 吃辣脖子肿了怎么办 脖子长了个肿瘤怎么办 一边背高一边低怎么办 生完孩子肩宽了怎么办 狗狗脖子上长囊肿怎么办 胸肋关节韧带疼怎么办 三岁宝宝有点驼背怎么办 20多岁有点驼背怎么办 五岁宝宝有点驼背怎么办 孕妇腰扭了很痛怎么办 怀孕了腰扭了疼怎么办 小龙芭比扭腰机开机没有声音怎么办 高中生训练数学计算的准确性怎么办 跑步累了跑不动了怎么办 一跑步就岔气了怎么办 婴儿关节折邹发红怎么办? 打了借条人跑了怎么办 吃凉的胃不舒服怎么办 跑步机带子跑偏怎么办 在跑步机上摔倒怎么办 弯道以后就是直线行驶怎么办 跑步机的声音大怎么办 科二一直考不过怎么办 考科目三太紧张怎么办 科目三太紧张了怎么办 跑步慢怎么办怎样跑快