在Android中模拟isDestroyed()

时间:2015-04-30 01:33:58

标签: android android-activity ondestroy

我发现我需要拨打isDestroyed()来测试某项活动是否不再有效。我做到了这一点,事情很有效。

然而,包含isDestroyed()迫使我将Android API级别提高到我不满意的级别(17)。我不想这样做。

我认为我可以简单地在我的活动中覆盖isDestroyed()来模拟onDestroy()。当调用该方法时,我可以简单地将此事实存储在布尔值中,然后使用它来提供我自己的isDestroyed()版本(更改当然的名称)。

这样的工作会如此简单吗?在某些情况下,我看到很多对onDestroy()未被调用的引用。有没有其他方法来模拟这个?

2 个答案:

答案 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 lookisDestroyed()如何实施。

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生命周期调用,或者没有理由实际销毁活动)。关于是否有其他方法来模拟这个,至少我想不出任何。