2022年2月25日 星期五

Android Studio - AsyncTask(非同步任務)(五十一)

Android Studio - AsyncTask(非同步任務)(五十一):

AsyncTask(非同步任務)允許我們的執行一個異步的任務在後台。我們可以將耗時的操作放在異步任務當中來執行,並隨時將任務執行的結果返回給我們的 UI 線程來更新我們的 UI 控件。通過 AsyncTask 我們可以輕鬆的解決多線程之間的通信問題。
※ AsyncTask 在 Android 11 (API level 30) 已經被廢棄 (deprecated) 了

Android Studio AsyncTask 過程
AsyncTask 的有五個步驟:
  • onPreExecute():處理前的最先動作,例如初始化某些參數或是顯示提示告訴使用者。
  • doInBackground(Void... arg0):實際背景處理的工作。
  • onProgressUpdate(Integer... values):處理過程中需要更新的動作,例如下載進度,在 doInBackground(Void... arg0) 中調用的方法為 publishProgress(values),其中參數 values 為整數陣列。
  • onPostExecute(String result):處理完的動作,例如提示使用者完成的訊息,或是更新介面。
  • onCancelled():當被取消時需要作的事,例如提示使用者任務取消,並更新介面。

AsyncTask 程式架構範例:

class GoodTask extends AsyncTask<Void, Integer, String> {

                // <傳入參數, 處理中更新介面參數, 處理後傳出參數>

    @Override

    protected String doInBackground(Void... arg0) {

        // TODO Auto-generated method stub

  

        // 再背景中處理的耗時工作

  

        return null; // 會傳給 onPostExecute(String result) String result

    }

 

    @Override

    protected void onPreExecute() {

        // TODO Auto-generated method stub

        super.onPreExecute();

 

        // 背景工作處理""需作的事

    }

 

    @Override

    protected void onProgressUpdate(Integer... values) {

        // TODO Auto-generated method stub

        super.onProgressUpdate(values);

  

        // 背景工作處理""更新的事

    }

 

    @Override

    protected void onPostExecute(String result) {

        // TODO Auto-generated method stub

        super.onPostExecute(result);

 

        // 背景工作處理完""需作的事

    }

 

    @Override

    protected void onCancelled() {

        // TODO Auto-generated method stub

        super.onCancelled();

  

        // 背景工作被"取消"時作的事,此時不作 onPostExecute(String result)

    }

}


AsyncTask 達成由  1 到 10 範例:

class GoodTask extends AsyncTask<Integer, Integer, String> {

                // <傳入參數, 處理中更新介面參數, 處理後傳出參數>

    int nowCount;

    @Override

    protected String doInBackground(Integer... countTo) {

        // TODO Auto-generated method stub

        // 再背景中處理的耗時工作

        try {

            for (int i = 0; i < countTo[0]; i++) {

                Thread.sleep(1000);

 

                nowCount = i + 1;

                publishProgress(nowCount);

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

        return "10";

    }

 

    @Override

    protected void onPreExecute() {

        // TODO Auto-generated method stub

        super.onPreExecute();

        // 背景工作處理""需作的事

        Toast.makeText(getApplicationContext(),

        "開始計時...", Toast.LENGTH_SHORT).show();

    }

 

    @Override

    protected void onProgressUpdate(Integer... values) {

        // TODO Auto-generated method stub

        super.onProgressUpdate(values);

        // 背景工作處理""更新的事

        txtCount.setText("目前計到 " + values[0] + " 秒。");

    }

 

    @Override

    protected void onPostExecute(String result) {

        // TODO Auto-generated method stub

        super.onPostExecute(result);

        // 背景工作處理完""需作的事

        Toast.makeText(getApplicationContext(),

        "接受到的完成參數為 "+ result + ",計時完成!!", Toast.LENGTH_SHORT).show();

    }

 

    @Override

    protected void onCancelled() {

        // TODO Auto-generated method stub

        super.onCancelled();

        // 背景工作被"取消"時作的事,此時不作 onPostExecute(String result)

        Toast.makeText(getApplicationContext(),

        "好可惜,計到 " + nowCount + " 秒!",  Toast.LENGTH_SHORT).show();

    }

}


AsyncTask 達成由 1 到 10 onCreate 範例:

@Override

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

       

    txtCount = (TextView) findViewById(R.id.txtCount);

    btnCancel = (Button) findViewById(R.id.btnCancel);

    btnStart = (Button) findViewById(R.id.btnStart);

       

    btnStart.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {

            // TODO Auto-generated method stub

            if (goodTask == null) {

                goodTask = new GoodTask();

                goodTask.execute(10);

            } else {

                if (goodTask.isCancelled()

                    || goodTask.getStatus().equals(AsyncTask.Status.FINISHED)) {

                    goodTask = new GoodTask();

                    goodTask.execute(10);

                }

            }

        }

   });

       

   btnCancel.setOnClickListener(new OnClickListener() {

       public void onClick(View v) {

           // TODO Auto-generated method stub

           if (goodTask != null) {

               if (!goodTask.isCancelled()

                   && goodTask.getStatus().equals(AsyncTask.Status.RUNNING)) {

                   goodTask.cancel(true);

               }

           }

       }

   });

}


AsyncTask 達成由 1 到 10 的 activity_main.xml 範例:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent" >

 

    <TextView

        android:id="@+id/txtCount"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_centerVertical="true"

        android:padding="@dimen/padding_medium"

        android:text="@string/hello_world"

        tools:context=".MainActivity" />

 

    <Button

        android:id="@+id/btnCancel"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_below="@+id/txtCount"

        android:layout_centerHorizontal="true"

        android:layout_marginTop="60dp"

        android:text="取消" />

 

    <Button

        android:id="@+id/btnStart"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_above="@+id/txtCount"

        android:layout_centerHorizontal="true"

        android:layout_marginBottom="73dp"

        android:text="開始" />

 

</RelativeLayout>


2022年 2月 25日(Fri)天氣報告
氣溫:27.0°F / -3.0°C @ 07:00
風速:每小時 3公里
降雨機會:2%
相對濕度:百分之 78%
天氣:晴

沒有留言:

張貼留言