我发现我需要拨打isDestroyed()
来测试某项活动是否不再有效。我做到了这一点,事情很有效。
然而,包含isDestroyed()
迫使我将Android API级别提高到我不满意的级别(17)。我不想这样做。
我认为我可以简单地在我的活动中覆盖isDestroyed()
来模拟onDestroy()
。当调用该方法时,我可以简单地将此事实存储在布尔值中,然后使用它来提供我自己的isDestroyed()
版本(更改当然的名称)。
这样的工作会如此简单吗?在某些情况下,我看到很多对onDestroy()
未被调用的引用。有没有其他方法来模拟这个?
答案 0 :(得分:1)
看作框架代码是:
devDependencies
我说你在public boolean isDestroyed() {
return mDestroyed;
}
final void performDestroy() {
mDestroyed = true;
mWindow.destroy();
mFragments.dispatchDestroy();
onDestroy();
if (mLoaderManager != null) {
mLoaderManager.doDestroy();
}
if (mVoiceInteractor != null) {
mVoiceInteractor.detachActivity();
}
}
中使用自己的标志就足够安全了,除了onDestroy
或{{1}中的某些内容崩溃之外,你会得到与使用Framework标志相同的结果}}
答案 1 :(得分:0)
它可能有效,具体取决于您何时需要检查isDestroyed()
。
如果您在isDestroyed()
回调中检查Fragment.onDestroy()
,则按照您的描述实施的模拟实施将返回false
,而Activity.isDestroyed()
将返回true
。如果您稍后检查isDestroyed()
“,则可以使用。您可以使用以下测试器应用验证这一点:
package com.example.test.myapplication;
import android.app.Activity;
import android.app.Fragment;
import android.os.Handler;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends Activity {
private boolean mOnDestroyCalled;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction().add(R.id.container, new MainFragment())
.commit();
}
}
@Override
protected void onDestroy() {
mOnDestroyCalled = true;
super.onDestroy();
}
public boolean isDestroyed_SIMULATED() {
return mOnDestroyCalled;
}
public static class MainFragment extends Fragment {
@Override
public void onDestroy() {
super.onDestroy();
final MainActivity mainActivity = (MainActivity)getActivity();
dumpIsDestroyedImplementations("In Fragment.onDestroy() ", mainActivity);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
dumpIsDestroyedImplementations("A while later ", mainActivity);
}
}, 500);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final TextView textView = new TextView(getActivity());
textView.setText("Hello world!");
return textView;
}
private void dumpIsDestroyedImplementations(String prefix, MainActivity mainActivity) {
Log.i("IsDestroyedTest", prefix + "isDestroyed(): " +
mainActivity.isDestroyed() +
" isDestroyed_SIMULATED(): " + mainActivity.isDestroyed_SIMULATED());
}
}
}
如果你运行它,然后按设备上的后退按钮,adb logcat -s IsDestroyedTest
会给你以下输出:
I/IsDestroyedTest( 2143): In Fragment.onDestroy() isDestroyed(): true isDestroyed_SIMULATED(): false
I/IsDestroyedTest( 2143): A while later isDestroyed(): true isDestroyed_SIMULATED(): true
要了解原因take a look,isDestroyed()
如何实施。
public boolean isDestroyed() {
return mDestroyed;
}
...
final void performDestroy() {
mDestroyed = true;
...
mFragments.dispatchDestroy();
onDestroy();
...
}
在这种情况下,我们可以在概念上将其重写如下:
final void performDestroy() {
mDestroyed = true;
...
MainFragment.onDestroy() // Called by mFragments.dispatchDestroy();
mOnDestroyCalled = true; // From MainActivity.onDestroy()
super.onDestroy(); // From MainActivity.onDestroy()
...
}
很容易理解为什么我们得到了logcat输出。
有时候onDestroy()
没有被调用,模拟isDestroyed()
时不会影响该问题。通常,如果没有调用,则有充分的理由(系统迫切需要释放内存,没有时间完成Activity生命周期调用,或者没有理由实际销毁活动)。关于是否有其他方法来模拟这个,至少我想不出任何。