1. 程式人生 > >使用AsyncTask實現非同步操作

使用AsyncTask實現非同步操作

一、更新ui元件的方法

1、使用Handlers實現執行緒之間的通訊

2、Activity.runOnUiThread(Runnable)

3、View.post(Runnable)

4、View.postDelayed(Runnable,long)

5、使用非同步操作AsyncTask

 

二、AsyncTask<Params,Progress,Result>是一個抽象類,通常繼承AsyncTask時需要指定如下的三個泛型引數。

1、Params啟動任務時輸入的引數型別

2、Progress後臺任務完成的進度型別

3、Result後臺任務完成返回的結果型別

 

三、根據需要實現AsyncTask的四個方法

1、doInBackground(Params...)該方法就是在後臺完成任務,呼叫publishProgress方法更新任務執行進度

2、onPostExecute(Result result) 當doInBackground(Params...)完成後,系統自動呼叫

3、onPreExecute()  該方法通常會完成一些初始化的準備工作,比如介面顯示進度條

4、onProgressUpdate當調在doInBackground中呼叫publishProgress時,觸發該方法

 

四、AsyncTask子類的例項,呼叫execute()方法,開始執行耗時操作,其中的四個方法都應該由系統自動呼叫

 

五、使用非同步操作任務執行下載任務

1、xml檔案

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="開始下載"
        android:onClick="download"
        android:layout_gravity="center"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/text1"/>

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="phone" />
    </LinearLayout>
</ScrollView>

2、activity

public class AsyncTaskActivity1 extends AppCompatActivity {
    private TextView text1;
    protected void onCreate(Bundle saveInstanceSate) {
        super.onCreate(saveInstanceSate);
        setContentView(R.layout.async_task);

        text1=findViewById(R.id.text1);
    }
    public void download(View view) throws MalformedURLException {
        DownTask downTask=new DownTask(this);

        //呼叫execute()方法開始執行非同步操作
        downTask.execute(new URL("https://luna.58.com/m/autotemplate?city=cd&creativeid=119&utm_source=link&spm=m-39558317773073-ms-f-801.mjh_daquanmingzhan01"));
    }

    //AsyncTask<Params,Progress,Result>
    //Params:啟動後臺執行任務輸入的引數  Progress:後臺任務完成的進度值的型別   Result:後臺執行任務完成後返回的結果型別
    class DownTask extends AsyncTask<URL,Integer,String>{
        //URL:為啟動後臺執行任務輸入的引數   Integer:後臺任務完成的進度值的型別  String:後臺執行任務完成後返回的結果型別

        ProgressDialog dialog;
        //定義記錄已經讀取的行數
        int hasRead=0;
        Context mContext;

        public DownTask(Context mContext) {
            this.mContext = mContext;
        }

        //(完成後臺下載)該方法後臺執行緒將要完成任務,呼叫publishProgress方法更新任務執行進度
        @Override
        protected String doInBackground(URL... urls) {
            StringBuilder sb=new StringBuilder();
            try{

                URLConnection conn=urls[0].openConnection();
                //將conn獲取的inputStream包裝為BufferedReader
                BufferedReader reader=new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line=null;
                while ((line=reader.readLine())!=null){
                    sb.append(line+"\n");
                    hasRead++;

                    //此方法更新任務的執行進度
                    publishProgress(hasRead);
                }
                return sb.toString();

                /*OkHttpClient client = new OkHttpClient();
                Request request = new Request.Builder()
                        .url("http://www.taobao.com")
                        .build();
                Response response = client.newCall(request).execute();
                String responseData = response.body().string();
                return responseData;*/

            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        //(在完成下載後將網頁的程式碼顯示)在doInBackground(URL... urls)完成後,系統自動呼叫該方法,並將doInBackground(URL... urls)的返回值床底給這個方法
        protected void onPostExecute(String result){
            text1.setText(result);
            dialog.dismiss();
        }

        //(開始下載前顯示一個進度條)該方法通常會完成一些初始化的準備工作,比如介面顯示進度條,將在後臺執行費時操作之前呼叫
        protected void onPreExecute(){
            dialog=new ProgressDialog(mContext);
            dialog.setTitle("任務正在進行");
            dialog.setMessage("任務正在進行中,敬請等待...");
            dialog.setCancelable(false);
            dialog.setMax(202);
            dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            dialog.setIndeterminate(false);
            dialog.show();
        }

        //(更新進度條)當調在doInBackground中呼叫publishProgress時,觸發該方法
        protected void onProgressUpdate(Integer... values){
            text1.setText("已經讀取到【"+values[0]+"】行!");
            dialog.setProgress(values[0]);
        }

    }
}