2010-06-12 13 views
0

我遇到了從UI線程運行AsyncTask的this android example。類ExportDatabaseTask聲明,並在活動實例,顯然有可能從onPreExecute和onPostExecute事件引用活動的UI背景下,這樣的:從異步任務訪問UI上下文

public class ManageData extends Activity { 

    private ExportDatabaseTask exportDatabaseTask; 
    [...] 

    @Override 
    public void onCreate(final Bundle savedInstanceState) { 
    [...] 
    ManageData.this.exportDatabaseTask = new ExportDatabaseTask(); 
    ManageData.this.exportDatabaseTask.execute(); 
    [...] 
    } 

    private class ExportDatabaseTask extends AsyncTask<String, Void, Boolean> { 
    private final ProgressDialog dialog = new ProgressDialog(ManageData.this); 

    protected void onPreExecute() { 
     this.dialog.setMessage("Exporting database..."); 
     this.dialog.show(); 
    } 

    protected Boolean doInBackground(final String... args) { 
     [...] 
    } 

    protected void onPostExecute(final Boolean success) { 
     if (this.dialog.isShowing()) { 
     this.dialog.dismiss(); 
     } 
    } 
} 

我試圖重構這一點,以便ExportDatabaseTask是由於各種原因在另一個不屬於Activity的類中聲明,我不知道如何使其工作。我在這裏缺乏一些基本的Java概念,我很樂意承認。

具體而言,onPreExecute()中myActivity爲null。這是爲什麼?

// this is a click event handler in my activity that starts the export 
public void onClick(View v) { 
    Exporter ex = new Exporter(getApplicationContext(), ActivityMain.this); 
    ex.exportDatabaseTask.execute(); 
} 

//this is the utility class 
public class Exporter { 

    public ExportDatabaseTask exportDatabaseTask; 
    private Context myContext; 
    private ActivityMain myActivity; 

    public Exporter(Context ctx, ActivityMain act) { 
      myContext = ctx; 
      myActivity = act; 

      this.exportDatabaseTask = new ExportDatabaseTask(); 
    } 

    public class ExportDatabaseTask extends AsyncTask<Void, Void, Boolean> { 
      private final ProgressDialog dialog = new ProgressDialog(myContext); 

     // can use UI thread here? 
     protected void onPreExecute() { 
     // ====> this throws a Nullpointer exception: 
     myActivity.dialog.setMessage("Exporting database..."); 
     myActivity.dialog.show(); 
     } 

     protected Boolean doInBackground(final Void... args) { 
     } 

     protected void onPostExecute(final Boolean success) { 
     if (myActivity.dialog.isShowing()) { 
      myActivity.dialog.dismiss(); 
     } 
     } 
    } 
} 

我知道我可以從預取碼和後執行的事件,並把它放到我的活動onclick處理程序,避免了這個問題,但我仍然好奇,爲什麼上面的代碼不起作用。

回答

2

規則1:永遠不要使用getApplicationContext()得到ContextActivityContext。您不需要另一個Context,而您從getApplicationContext()獲得的Context對於與GUI相關的操作完全無法使用。

現在,有了這樣的方式......

顯然有可能從 onPreExecute和onPostExecute事件

ExportDatabaseTask是一家民營inner class引用 活動的UI背景的Activity。 Java中的內部類可以訪問外部類的方法和數據成員。

具體地說,myActivity爲空在 onPreExecute()。這是爲什麼?

我懷疑它是。我懷疑myActivity中的對話框是null。這也會給你在指定的線上NullPointerException

+0

感謝您的解釋。我決定這樣的工具類不包含UI代碼,我將對話移到了調用者。 – cdonner 2010-06-13 01:35:53