在AsyncTask执行时,方向更改会中断禁用按钮

时间:2011-06-23 04:58:17

标签: android orientation android-asynctask

我有一个Activity,它开始执行AsyncTask以响应单击Button小部件。我在使用setEnabled(false)单击时禁用Button。 AsyncTask在完成时调用Activity上的回调方法。我在回调中的Button上调用setEnabled(true)以在AsyncTask完成时重新启用Button。这一切都正常,直到AsyncTask执行时方向发生变化。我已经尝试了很多不同的东西,以便在发生这种情况时正确启用/禁用Button,我无法使其正常工作。即使在执行AsyncTask时方向发生变化,使其工作的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

当再次调用应用程序onCreate方法中的方向chaneg时,您已在onCreate方法中编写了所有逻辑。因此,当方向改变时,不要让你的应用程序进入onCreate()方法

将以下内容添加到清单中的活动声明:

android:configChanges="orientation"

所以它看起来像

<activity android:label="@string/app_name" 
        android:configChanges="orientation|keyboardHidden" 
        android:name=".your.package">

答案 1 :(得分:0)

我认为您不需要开始拦截方向更改。如果您真的想要为不同的方向加载不同的资源,那么它的切角和它可能会让您感到很头疼。

根本问题是AsyncTask对其意图更新的按钮的引用是陈旧的,它指的是您的旧按钮。你可以做的就是实现Activity.onRetainNonConfigurationInstanceState()。在方向更改发生的情况下调用此方法,并允许您存储非配置特定的项,如运行线程。

您需要的另一件事是AsyncTask中的一个方法来设置它应该启用/禁用的Button。当您的Activity重新启动时,您取消设置Button,然后在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);
      }
    }
  }
}