|
AsyncTask "非同步任務" 在多執行序的情況下, 提供了更多的優點和更容易處理UI 元件, AsyncTask 已經幫我們定義處理前、後、中都可以去更新 UI 介面的方法, 也定義好在各狀態下傳送資料的參數.
實作完成的畫面如下:
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)
- }
- }
複製代碼
當你在看這篇之前, 你需要先會:
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 , 使用下面的設定值:
- <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: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>
複製代碼
Step 3:
主程式 MainActivity.java , 加入下面 的程式碼.
- TextView txtCount;
- Button btnCancel;
- Button btnStart;
- GoodTask goodTask;
- @Override
- protected 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() {
- @Override
- 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() {
- @Override
- 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);
- }
- }
- }
- });
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.activity_main, menu);
- return true;
- }
- 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();
- }
- }
複製代碼
附註: 貼上程式碼到Eclipse後, 有幾個Error 的地方需要手動點一下, import. (太簡單了, 略過貼圖, 操作的圖片, 可以參考看看前幾篇文章).
Step 4:
用 Run As執行看看App, 按下 "開始" 按鈕後的執行畫面如下:
按下 "取消" 按鈕後的畫面:
文章來源
|
|