Доступ к контексту пользовательского интерфейса из асинхронной задачи - PullRequest
1 голос
/ 13 июня 2010

Я сталкивался с этим примером Android , который запускает AsyncTask из потока пользовательского интерфейса.Класс ExportDatabaseTask объявлен и создан в Activity, и, по-видимому, можно ссылаться на контекст пользовательского интерфейса действия из событий 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<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, которые я с готовностью признаю.

В частности, myActivity имеет значение null в 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<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();
         }
       }
     }
}

Я понимаю, что могу взять код из событий pre и post-execute и поместить его в обработчик onclick в своей деятельности, избегая этого вопроса, но мне все еще интересно, почемукод выше не работает.

1 Ответ

2 голосов
/ 13 июня 2010

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

Теперь, с этим с дороги ...

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...