Android 線程操作之AsyncTask

來源:互聯網
上載者:User

標籤:android   style   blog   http   io   ar   color   os   使用   


AsyncTask和Handler對比

1 ) AsyncTask實現的原理,和適用的優缺點

AsyncTask,是android提供的輕量級的非同步類,可以直接繼承AsyncTask,在類中實現非同步作業,並提供介面反饋當前非同步執行的程度(可以通過介面實現UI進度更新),最後反饋執行的結果給UI主線程.

使用的優點:

l  簡單,快捷

l  過程可控


使用的缺點:

l  在使用多個非同步作業和並需要進行Ui變更時,就變得複雜起來.

2 )Handler非同步實現的原理和適用的優缺點

在Handler 非同步實現時,涉及到 Handler, Looper, Message,Thread四個對象,實現非同步流程是主線程啟動Thread(子線程)àthread(子線程)運行並產生Message-àLooper擷取Message並傳遞給HandleràHandler逐個擷取Looper中的Message,並進行UI變更。

使用的優點:

l  結構清晰,功能定義明確

l  對於多個背景工作時,簡單,清晰

  
使用的缺點:

l  在單個後台非同步處理時,顯得代碼過多,結構過於複雜(相對性)
 
AsyncTask介紹
Android的AsyncTask比Handler更輕量級一些,適用於簡單的非同步處理。
首先明確Android之所以有Handler和AsyncTask,都是為了不阻塞主線程(UI線程),且UI的更新只能在主線程中完成,因此非同步處理是不可避免的。
 

Android為了降低這個開發難度,提供了AsyncTask。AsyncTask就是一個封裝過的背景工作類,顧名思義就是非同步任務。AsyncTask是對Thread+Handler良好的封裝。

AsyncTask直接繼承於Object類,位置為android.os.AsyncTask。要使用AsyncTask工作我們要提供三個泛型參數,並重載幾個方法(至少重載一個)。

 

AsyncTask定義了三種泛型型別 Params,Progress和Result。

    Params 啟動任務執行的輸入參數,比如HTTP請求的URL。
    Progress 背景工作執行的百分比。
    Result 後台執行任務最終返回的結果,比如String。

使用過AsyncTask 的同學都知道一個非同步載入資料最少要重寫以下這兩個方法:

    doInBackground(Params…) 後台執行,比較耗時的操作都可以放在這裡。注意這裡不能直接操作UI。此方法在後台線程執行,完成任務的主要工作,通常需要較長的時間。在執行過程中可以調用publicProgress(Progress…)來更新任務的進度。
    onPostExecute(Result)  相當於Handler 處理UI的方式,在這裡面可以使用在doInBackground 得到的結果處理操作UI。 此方法在主線程執行,任務執行的結果作為此方法的參數返回

有必要的話你還得重寫以下這三個方法,但不是必須的:

    onProgressUpdate(Progress…)   可以使用進度條增加使用者體驗度。 此方法在主線程執行,用於顯示任務執行的進度。
    onPreExecute()        這裡是終端使用者調用Excute時的介面,當任務執行之前開始調用此方法,可以在這裡顯示進度對話方塊。
    onCancelled()             使用者調用取消時,要做的操作

中斷線程時可以調用AsyncTask.cancle(true)方法,之後會調用onCancelled()方法
    
使用AsyncTask類,以下是幾條必須遵守的準則:

    Task的執行個體必須在UI thread中建立;
    execute方法必須在UI thread中調用;
    不要手動的調用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法;
    該task只能被執行一次,否則多次調用時將會出現異常;

/** *Layout XML **/<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent">    <Button        android:id="@+id/execute"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="execute"/>    <Button        android:id="@+id/cancel"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:enabled="false"        android:text="cancel"/>    <ProgressBar        android:id="@+id/progress_bar"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:progress="0"        android:max="100"        style="?android:attr/progressBarStyleHorizontal"/>    <ScrollView        android:layout_width="fill_parent"        android:layout_height="wrap_content">        <TextView            android:id="@+id/text_view"            android:layout_width="fill_parent"            android:layout_height="wrap_content"/>    </ScrollView></LinearLayout>

 

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

 

/** *Activity code **/package com.scott.async;import java.io.ByteArrayOutputStream;import java.io.InputStream;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.HttpStatus;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ProgressBar;import android.widget.TextView;public class MainActivity extends Activity {      private static final String TAG = "ASYNC_TASK";      private Button execute;  private Button cancel;  private ProgressBar progressBar;  private TextView textView;      private MyTask mTask;  @Override  public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                execute = (Button) findViewById(R.id.execute);        execute.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //注意每次需new一個執行個體,建立的任務只能執行一次,否則會出現異常                mTask = new MyTask();                mTask.execute("http://www.baidu.com");                                execute.setEnabled(false);                cancel.setEnabled(true);            }        });        cancel = (Button) findViewById(R.id.cancel);        cancel.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //取消一個正在執行的任務,onCancelled方法將會被調用                mTask.cancel(true);            }        });        progressBar = (ProgressBar) findViewById(R.id.progress_bar);        textView = (TextView) findViewById(R.id.text_view);            }        private class MyTask extends AsyncTask<String, Integer, String> {        //onPreExecute方法用於在執行背景工作前做一些UI操作        @Override        protected void onPreExecute() {            Log.i(TAG, "onPreExecute() called");            textView.setText("loading...");        }                //doInBackground方法內部執行背景工作,不可在此方法內修改UI        @Override        protected String doInBackground(String... params) {            Log.i(TAG, "doInBackground(Params... params) called");            try {                HttpClient client = new DefaultHttpClient();                HttpGet get = new HttpGet(params[0]);                HttpResponse response = client.execute(get);                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {                    HttpEntity entity = response.getEntity();                    InputStream is = entity.getContent();                    long total = entity.getContentLength();                    ByteArrayOutputStream baos = new ByteArrayOutputStream();                    byte[] buf = new byte[1024];                    int count = 0;                    int length = -1;                    while ((length = is.read(buf)) != -1) {                        baos.write(buf, 0, length);                        count += length;                        //調用publishProgress公布進度,最後onProgressUpdate方法將被執行                        publishProgress((int) ((count / (float) total) * 100));                        //為了示範進度,休眠500毫秒                        Thread.sleep(500);                    }                    return new String(baos.toByteArray(), "gb2312");                }            } catch (Exception e) {                Log.e(TAG, e.getMessage());            }            return null;        }                //onProgressUpdate方法用於更新進度資訊        @Override        protected void onProgressUpdate(Integer... progresses) {            Log.i(TAG, "onProgressUpdate(Progress... progresses) called");            progressBar.setProgress(progresses[0]);            textView.setText("loading..." + progresses[0] + "%");        }                //onPostExecute方法用於在執行完背景工作後更新UI,顯示結果        @Override        protected void onPostExecute(String result) {            Log.i(TAG, "onPostExecute(Result result) called");            textView.setText(result);                        execute.setEnabled(true);            cancel.setEnabled(false);        }                //onCancelled方法用於在取消執行中的任務時更改UI        @Override        protected void onCancelled() {            Log.i(TAG, "onCancelled() called");            textView.setText("cancelled");            progressBar.setProgress(0);                        execute.setEnabled(true);            cancel.setEnabled(false);        }    }}

 

Android 線程操作之AsyncTask

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.