Доступ к контексту UI от асинхронной задачи

Я столкнулся с этим примером андроида, который выполняет AsyncTask от потока UI. Класс ExportDatabaseTask объявляют и инстанцируют в Действии, и по-видимому возможно сослаться на контекст UI действия от onPreExecute и onPostExecute событий, как это:

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 { 
    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 был объявлен в другом классе, который не является Действием по различным причинам, и я не могу вполне выяснить, как заставить его работать. Я испытываю недостаток в некоторых основных понятиях Java здесь, которые я с готовностью допускаю.

А именно, myActivity является пустым в onPreExecute (). Почему это?

// 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 {
            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
задан cdonner 12 June 2010 в 22:26
поделиться

1 ответ

Правило №1: Никогда не используйте getApplicationContext () для получения контекста . Действие является Контекстом . Вам не нужен другой Контекст , а Контекст , который вы получаете из getApplicationContext () , совершенно непригоден для операций, связанных с графическим интерфейсом пользователя.

Теперь, разобравшись с этим ...

очевидно, можно сослаться на контекст пользовательского интерфейса действия из События onPreExecute и onPostExecute

ExportDatabaseTask - это частный внутренний класс действия Activity . Внутренние классы в Java имеют доступ к методам и членам данных своего внешнего класса.

В частности, myActivity имеет значение null в onPreExecute (). Почему?

Сомневаюсь. Я подозреваю, что диалоговое окно null внутри myActivity . Это тоже даст вам NullPointerException в указанной строке.

2
ответ дан 2 September 2019 в 23:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: