2013-03-18 58 views
11

我一直在玩弄各種試圖熟悉AsyncTask的例子。到目前爲止,我所見過的所有例子都將AsyncTask包含在主要活動的onCreate方法中。我不太喜歡它,所以我想看看把它分成它自己的班級有多難。到目前爲止,我有這樣的:Android開發:在一個單獨的類文件中有一個AsyncTask

主要活動

package com.example.asynctaskactivity; 

import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.SystemClock; 
import android.app.Activity; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.ProgressBar; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.example.asynctaskactivity.ShowDialogAsyncTask; 

public class AsyncTaskActivity extends Activity { 

Button btn_start; 
ProgressBar progressBar; 
TextView txt_percentage; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     btn_start = (Button) findViewById(R.id.btn_start); 
     progressBar = (ProgressBar) findViewById(R.id.progress); 
     txt_percentage= (TextView) findViewById(R.id.txt_percentage); 
     Log.v("onCreate","Attempt set up button OnClickListener"); 
     btn_start.setOnClickListener(new View.OnClickListener() 
     { 
      @Override 
      public void onClick(View v) { 
       btn_start.setEnabled(false); 
       new ShowDialogAsyncTask().execute(); 
      } 
     }); 

     Log.v("onCreate","Success!"); 
    } 
} 

新的獨立的AsyncTask類

package com.example.asynctaskactivity; 

import android.os.AsyncTask; 
import android.os.SystemClock; 
import android.util.Log; 
import android.widget.Button; 
import android.widget.ProgressBar; 
import android.widget.TextView; 
import android.widget.Toast; 

public class ShowDialogAsyncTask extends AsyncTask<Void, Integer, Void>{ 
int progress_status; 

@Override 
    protected void onPreExecute() { 
    // update the UI immediately after the task is executed 
    Log.v("onPreExecute","1"); 
    super.onPreExecute(); 
    Log.v("onPreExecute","2"); 
    //Toast.makeText(AsyncTaskActivity.this,"Invoke onPreExecute()", Toast.LENGTH_SHORT).show(); 
    progress_status = 0; 
    Log.v("onPreExecute","3"); 
    txt_percentage.setText("downloading 0%"); 
    Log.v("onPreExecute","4"); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     Log.v("doInBackground","1"); 
     while(progress_status<100){ 

      progress_status += 2; 

      publishProgress(progress_status); 
      SystemClock.sleep(300); 

     } 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
    super.onProgressUpdate(values); 

    progressBar.setProgress(values[0]); 
    txt_percentage.setText("downloading " +values[0]+"%"); 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
    super.onPostExecute(result); 

    //Toast.makeText(AsyncTaskActivity.this,"Invoke onPostExecute()", Toast.LENGTH_SHORT).show(); 

    txt_percentage.setText("download complete"); 
    btn_start.setEnabled(true); 
    } 
} 

原來這一切都是在主要活動,因此提到的asynctask理論上應該更新的元素。顯然目前這造成了運行時錯誤,這讓我想到了。我怎樣才能讓文件分離,但仍然更新UI線程。

對不起,如果這是一個愚蠢的問題,特別是對於android開發和後臺線程來說很新。

+0

看起來非常像這個http:// stackoverflow。com/questions/6119305/android-how-to-run-asynctask-from-different-class-file – user2070018 2013-03-18 22:08:34

+1

作爲旁註,你不需要在'AsyncTask'中調用超級方法,它們什麼都不做。 – nhaarman 2013-03-18 22:09:37

+0

實際上他們有什麼意義呢,我注意到他們有很多我正在看的asynctasks的例子,他們無法弄清楚他們的目的。 – cosmicsafari 2013-03-18 22:10:21

回答

17

如何讓文件分離但仍然更新UI線程。

Okey。所以起初你知道AsyncTask在Activity中作爲內部類添加的主要優點是你可以直接訪問所有UI元素,並且它可以實現相當「輕量級」的UI更新。

但是,如果你決定做的AsyncTask從活動中分離出來(這也有一定的益處EQ代碼更乾淨,應用邏輯是從外觀分離)類,你可以:

這就是你所需要的所有我猜。

8

添加一個回調接口,並讓你的Activity實現它。

public interface MyAsyncTaskCallback{ 
    public void onAsyncTaskComplete(); 
} 

在postexecute:

myAsyncTaskCallback.onAsyncTaskComplete(); 

在構造函數中你AsyncTask你可以傳遞的MyAsyncTaskCallback實例(您Activity)。

1

處理此問題的最佳方法是通過處理程序。在活動中實例化並覆蓋方法handleMessage()。當您創建ShowDialogAsyncTask類時,只需傳遞處理程序並維護對其的引用即可。在postExecute上,你可以構造一個消息並通過處理器方法sendMessage()發送消息。前面提到的一個使用接口和回調範例的回答。這將起作用,但是,當執行postExecute方法時,活動可能會被銷燬並且不會存在,因此您需要測試此操作。

相關問題