从asynctask访问UI上下文

时间:2010-06-12 22:01:09

标签: android user-interface multithreading

我遇到了this android example,它从UI线程运行AsyncTask。 ExportDatabaseTask类在Activity中声明并实例化,显然可以从onPreExecute和onPostExecute事件引用活动的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(); 
      } 
    } 
} 

我正在尝试重构这个,以便出于各种原因在另一个不是Activity的类中声明ExportDatabaseTask,我无法弄清楚如何使它工作。我在这里缺少一些基本的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处理程序中,避免这个问题,但我仍然很好奇为什么上面的代码不起作用。

1 个答案:

答案 0 :(得分:2)

规则#1:永远不要使用getApplicationContext()来获取ContextActivityContext。您不需要另一个Context,而Context获得的getApplicationContext()完全无法用于与GUI相关的操作。

现在,开始了......

  显然有可能参考   来自的活动的UI上下文   onPreExecute和onPostExecute事件

ExportDatabaseTaskActivity的私人inner class。 Java中的内部类可以访问其外部类的方法和数据成员。

  

具体来说,myActivity为空   onPreExecute()。那是为什么?

我对此表示怀疑。我怀疑null内的对话框是myActivity。这也会在指定的行上显示NullPointerException