изменение ориентации нарушает отключение кнопки во время выполнения AsyncTask - PullRequest
0 голосов
/ 23 июня 2011

У меня есть Activity, которая начинает выполнять AsyncTask в ответ на щелчок виджета Button. Я отключаю кнопку, когда она нажата, используя setEnabled (false). AsyncTask вызывает метод обратного вызова в Activity, когда он завершается. Я вызываю setEnabled (true) для Button в обратном вызове, чтобы повторно активировать Button после завершения AsyncTask. Это все работает нормально, пока ориентация не изменится во время выполнения AsyncTask. Я пробовал много разных вещей, чтобы правильно включить / отключить кнопку, когда это происходит, и я не могу заставить ее работать правильно. Как правильно выполнить эту работу, даже если ориентация меняется во время выполнения AsyncTask?

Ответы [ 2 ]

1 голос
/ 23 июня 2011

Когда ориентация изменяется в вашем приложении, метод onCreate вызывается снова, и вы записали всю логику в методе onCreate.поэтому при изменении ориентации приложение не должно обращаться к методу onCreate ()

Добавьте следующее в объявление действия в манифесте:

android:configChanges="orientation"

, чтобы оно выглядело как

<activity android:label="@string/app_name" 
        android:configChanges="orientation|keyboardHidden" 
        android:name=".your.package">
0 голосов
/ 27 июня 2011

Не думаю, что вам нужно начинать перехватывать изменения ориентации. Его режущие углы и, возможно, вызовут у вас много головной боли, если вы действительно захотите сделать что-то вроде загрузки разных ресурсов для разных ориентаций.

Основная проблема заключается в том, что ссылка, которую AsyncTask имеет на кнопку, предназначенную для обновления, устарела, она ссылается на вашу старую кнопку. Что вы можете сделать, чтобы решить эту проблему - реализовать Activity.onRetainNonConfigurationInstanceState(). Этот метод вызывается в ситуациях, когда происходит изменение ориентации, и он позволяет вам хранить элементы, которые не зависят от конфигурации, например, запуск потоков.

Другая вещь, которая вам нужна, - это метод в AsyncTask для установки кнопки, которую он должен включать / отключать. Пока ваша активность перезапускается, вы сбрасываете кнопку и затем сбрасываете ее в onCreate ().

Реализация может выглядеть примерно так.

public class MyActivity extends Activity {
  private static final String NON_CONFIG_KEY = "com.example.NON_CONFIG_KEY";
  protected void onCreate(Bundle instanceState) {
    setContentView(R.layout.main);
    HashMap<String, Object> nonConfigState = (HashMap<String, Object>)
        getLastNonConfigurationIntstanceState();
    if (nonConfigState != null && nonConfigState.get(NON_CONFIG_KEY) != null) {
      MyAsyncTask task = (MyAsyncTask) nonConfigState.get(NON_CONFIG_KEY);
      task.setUiControl(findViewById(R.id.my_button));
    }
  }

  public Object onRetainNonConfigurationInstanceState() {
    task.setUiControl(null);
    // create HashMap, store AsyncTask in it, and return it
  }
}

public MyAsyncTask extends AsyncTask {

  private Button mControl = null;
  private boolean shouldUpdateControl = false;
  private Object mLock = new Object();

  public void setUiControl(Button b) {
    synchronized (mLock) {
      if (b != null && shouldUpdateControl) {
        b.setEnabled(true);
        shouldUpdateControl = false;
      }
      mControl = b;
    }
  }

  protected void onPostExecute(Result r) {
    synchronized (mLock) {
      if (mControl == null) {
        shouldUpdateControl = true;
      } else {
        mControl.setEnabled(true);
      }
    }
  }
}
...