TShopping

 找回密碼
 註冊
搜索
查看: 221|回復: 0

[教學] Android AsyncTask (非同步任務)

[複製鏈接]
發表於 2016-2-15 22:32:04 | 顯示全部樓層 |閱讀模式
 
Push to Facebook Push to Plurk Push to Twitter 

AsyncTask "非同步任務" 在多執行序的情況下, 提供了更多的優點和更容易處理UI 元件, AsyncTask 已經幫我們定義處理前、後、中都可以去更新 UI 介面的方法, 也定義好在各狀態下傳送資料的參數.

實作完成的畫面如下:

1.jpg


AsyncTask的架構,如下:
  1. class GoodTask extends AsyncTask<Void, Integer, String> {
  2.                 // <傳入參數, 處理中更新介面參數, 處理後傳出參數>
  3.     @Override
  4.     protected String doInBackground(Void... arg0) {
  5.         // TODO Auto-generated method stub
  6.    
  7.         // 再背景中處理的耗時工作
  8.    
  9.         return null;
  10. // 會傳給 onPostExecute(String result) 的 String result
  11.     }

  12.     @Override
  13.     protected void onPreExecute() {
  14.         // TODO Auto-generated method stub
  15.         super.onPreExecute();

  16.         // 背景工作處理"前"需作的事
  17.     }

  18.     @Override
  19.     protected void onProgressUpdate(Integer... values) {
  20.         // TODO Auto-generated method stub
  21.         super.onProgressUpdate(values);
  22.    
  23.         // 背景工作處理"中"更新的事
  24.     }
  25.    
  26.     @Override
  27.     protected void onPostExecute(String result) {
  28.         // TODO Auto-generated method stub
  29.         super.onPostExecute(result);

  30.         // 背景工作處理完"後"需作的事
  31.     }

  32.     @Override
  33.     protected void onCancelled() {
  34.         // TODO Auto-generated method stub
  35.         super.onCancelled();
  36.    
  37.         // 背景工作被"取消"時作的事,此時不作 onPostExecute(String result)
  38.     }
  39. }
複製代碼






當你在看這篇之前, 你需要先會:
Eclipse 裡的如何寫物件的事件程式碼
http://imax-live.blogspot.tw/2012/11/eclipse-converter-22-coding-tutorial.html
以下是我的操作流程:

Step 1:
建立一個空白的專案.
Application name, 叫AsyncTask 測試.


Step 2:
修改 layout目錄下的 activity_main.xml , 使用下面的設定值:
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.     xmlns:tools="http://schemas.android.com/tools"
  3.     android:layout_width="fill_parent"
  4.     android:layout_height="fill_parent" >

  5.     <TextView
  6.         android:id="@+id/txtCount"
  7.         android:layout_width="wrap_content"
  8.         android:layout_height="wrap_content"
  9.         android:layout_centerHorizontal="true"
  10.         android:layout_centerVertical="true"
  11.         android:text="@string/hello_world"
  12.         tools:context=".MainActivity" />

  13.     <Button
  14.         android:id="@+id/btnCancel"
  15.         android:layout_width="wrap_content"
  16.         android:layout_height="wrap_content"
  17.         android:layout_below="@+id/txtCount"
  18.         android:layout_centerHorizontal="true"
  19.         android:layout_marginTop="60dp"
  20.         android:text="取消" />

  21.     <Button
  22.         android:id="@+id/btnStart"
  23.         android:layout_width="wrap_content"
  24.         android:layout_height="wrap_content"
  25.         android:layout_above="@+id/txtCount"
  26.         android:layout_centerHorizontal="true"
  27.         android:layout_marginBottom="73dp"
  28.         android:text="開始" />

  29. </RelativeLayout>
複製代碼



Step 3:
主程式 MainActivity.java , 加入下面  的程式碼.
  1. TextView txtCount;
  2. Button btnCancel;
  3. Button btnStart;
  4. GoodTask goodTask;

  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7.     super.onCreate(savedInstanceState);
  8.     setContentView(R.layout.activity_main);

  9.     txtCount = (TextView) findViewById(R.id.txtCount);
  10.     btnCancel = (Button) findViewById(R.id.btnCancel);
  11.     btnStart = (Button) findViewById(R.id.btnStart);

  12.     btnStart.setOnClickListener(new OnClickListener() {
  13.         @Override
  14.         public void onClick(View v) {
  15.             // TODO Auto-generated method stub
  16.             if (goodTask == null) {
  17.                 goodTask = new GoodTask();
  18.                 goodTask.execute(10);
  19.             } else {
  20.                 if (goodTask.isCancelled()
  21.                     || goodTask.getStatus().equals(AsyncTask.Status.FINISHED)) {
  22.                     goodTask = new GoodTask();
  23.                     goodTask.execute(10);
  24.                 }
  25.             }
  26.         }
  27.     });

  28.     btnCancel.setOnClickListener(new OnClickListener() {
  29.         @Override
  30.         public void onClick(View v) {
  31.            // TODO Auto-generated method stub
  32.            if (goodTask != null) {
  33.                if (!goodTask.isCancelled()
  34.                    && goodTask.getStatus().equals(AsyncTask.Status.RUNNING)) {
  35.                    goodTask.cancel(true);
  36.                }
  37.            }
  38.        }
  39.     });
  40. }

  41. @Override
  42. public boolean onCreateOptionsMenu(Menu menu) {
  43.     // Inflate the menu; this adds items to the action bar if it is present.
  44.     getMenuInflater().inflate(R.menu.activity_main, menu);
  45.     return true;
  46. }


  47. class GoodTask extends AsyncTask<Integer, Integer, String> {
  48.     // <傳入參數, 處理中更新介面參數, 處理後傳出參數>
  49.     int nowCount;
  50.     @Override
  51.     protected String doInBackground(Integer... countTo) {
  52.         // TODO Auto-generated method stub
  53.         // 再背景中處理的耗時工作
  54.         try {
  55.             for (int i = 0; i < countTo[0]; i++) {
  56.                 Thread.sleep(1000);

  57.                 nowCount = i + 1;
  58.                 publishProgress(nowCount);
  59.             }
  60.         } catch (Exception e) {
  61.             e.printStackTrace();
  62.         }
  63.         return "10";
  64.     }

  65.     @Override
  66.     protected void onPreExecute() {
  67.         // TODO Auto-generated method stub
  68.         super.onPreExecute();
  69.         // 背景工作處理"前"需作的事
  70.         Toast.makeText(getApplicationContext(), "開始計時...", Toast.LENGTH_SHORT).show();
  71.     }

  72.     @Override
  73.     protected void onProgressUpdate(Integer... values) {
  74.         // TODO Auto-generated method stub
  75.         super.onProgressUpdate(values);
  76.         // 背景工作處理"中"更新的事
  77.         txtCount.setText("目前計到 " + values[0] + " 秒。");
  78.     }

  79.     @Override
  80.     protected void onPostExecute(String result) {
  81.         // TODO Auto-generated method stub
  82.         super.onPostExecute(result);
  83.         // 背景工作處理完"後"需作的事
  84.         Toast.makeText(getApplicationContext(),
  85.         "接受到的完成參數為 "+ result + ",計時完成!!", Toast.LENGTH_SHORT).show();
  86.     }

  87.     @Override
  88.     protected void onCancelled() {
  89.         // TODO Auto-generated method stub
  90.         super.onCancelled();
  91.         // 背景工作被"取消"時作的事,此時不作 onPostExecute(String result)
  92.         Toast.makeText(getApplicationContext(),
  93.         "好可惜,計到 " + nowCount + " 秒!",  Toast.LENGTH_SHORT).show();
  94.     }
  95. }
複製代碼


附註: 貼上程式碼到Eclipse後, 有幾個Error 的地方需要手動點一下, import. (太簡單了, 略過貼圖, 操作的圖片, 可以參考看看前幾篇文章).



Step 4:
用 Run As執行看看App, 按下 "開始" 按鈕後的執行畫面如下:

2.jpg


按下 "取消" 按鈕後的畫面:
3.jpg

文章來源


 

臉書網友討論
您需要登錄後才可以回帖 登錄 | 註冊 |

本版積分規則



Archiver|手機版|小黑屋|免責聲明|TShopping

GMT+8, 2016-12-7 07:51 , Processed in 0.060430 second(s), 25 queries .

本論壇言論純屬發表者個人意見,與 TShopping綜合論壇 立場無關 如有意見侵犯了您的權益 請寫信聯絡我們。

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表