我想我知道为什么会这样。
当旋转屏幕时,Activity被销毁并重新创建,runOnUiThread()
方法引用旧的(已破坏的)Activity,它不再有效,因此android会抛出runtimeexception
。
为了证明这一点,我有这段代码:
@ContentView(R.layout.activity_start)
public class StartActivity extends RoboSherlockFragmentActivity {
@Inject
private EventManager eventManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
Fragment newFragment = new WelcomeFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, newFragment).commit();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
//Do some short initialization here like read shared prefs
//and then decide for example whether to login or skip the login
//If the rotation happens while sleeping the app will certainly crash
runOnUiThread(new Runnable() {
@Override
public void run() {
addFragmentToStack();
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
}).start();
}
}
void addFragmentToStack() {
Fragment newFragment = new LoginOrRegisterFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, newFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
}
}
我是否必须使用asynctask
这样的简单任务?如果是这样我怎么处理轮换呢?因为回调引用也会出错。
答案 0 :(得分:1)
try this
new Handler(getMainLooper()).postDelayed(new Runnable(){
if(!isFinishing()){
addFragmentToStack();
}
},200);
代替你的线程代码
当活动处于被摧毁的过程中时,会调用 isFinishing()
似乎你所要做的就是在200毫秒过后执行任务。
没有必要为此打开一个新线程,处理程序将执行
如果您想确保代码将在主线程上执行,请更加友好
你创建了一个调用主循环器的处理程序
Handler(getMainLooper())
它将使此处理程序在主线程上执行其任务
答案 1 :(得分:0)
AsyncTask会产生同样的崩溃。您可以简单地覆盖onPause()
并找到一种方法来通知线程即将销毁Activity。就像检查变量的空值一样。
public void run() {
if(someVariable != null)
addFragmentToStack();
}
或者您可以使用回调片段(不带视图)来跟踪配置更改。这个article是一个很好的开始。我更喜欢这种方法,因为它是一种非常干净的方法。
答案 2 :(得分:0)
我遇到了类似的问题并通过使用保留片段解决了这个问题,我在每个OnCreate上存储对Activity的引用,例如retainFragment.activity = this; 。在runOnUiThread中,我检查保留的引用是否是当前的Activity,例如if(retainFragment.activity == MainActivity.this)..