您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

在onPause,onStop和onDestroy方法中调用超类方法的正确顺序是什么?为什么?

在onPause,onStop和onDestroy方法中调用超类方法的正确顺序是什么?为什么?

首先销毁实例特定的资源,然后销毁实例特定资源可能依赖的超类资源是有道理的,而不是相反。但是这些评论暗示了另外的观点。

我认为:没有一件事情。

Mark的这个答案(又名SO上的CommonsWare)阐明了这个问题:链接- 对超类方法的调用应该是第一个语句吗?。但是,您可以在他的答案中看到以下评论

但是,为什么官方文档在onPause()中说:“总是先调用超类方法”?

回到原点。好吧,让我们从另一个角度来看这个。我们知道Java语言规范 指定super.overridenMethod()必须放置调用的顺序(或者是否必须放置调用)。

如果是Activity类,super.overridenMethod()则必须 执行@H_403_20@ 调用

if (!mCalled) {
    throw new SuperNotCalledException(
        "Activity " + mComponent.toShortString() +
            " did not call through to super.onStop()");
}

mCalled在中设置为true Activity.onStop()

现在,唯一需要讨论的细节是订购。

I also kNow that both work

当然。查看Activity.onPause()的方法主体:

protected void onPause() {
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this);

    // This is to invoke 
    // Application.ActivityLifecyleCallbacks.onActivityPaused(Activity)
    getApplication().dispatchActivityPaused(this);

    // The flag to enforce calling of this method
    mCalled = true;
}

无论采用哪种方式将呼叫夹在上super.onPause(),您都可以。Activity.onStop()具有相似的方法主体。但是看看Activity.onDestroy():

protected void onDestroy() {
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
    mCalled = true;

    // dismiss any dialogs we are managing.
    if (mManagedDialogs != null) {
        final int numDialogs = mManagedDialogs.size();
        for (int i = 0; i < numDialogs; i++) {
            final ManagedDialog md = mManagedDialogs.valueAt(i);
            if (md.mDialog.isShowing()) {
                md.mDialog.dismiss();
            }
        }
        mManagedDialogs = null;
    }

    // close any cursors we are managing.
    synchronized (mManagedCursors) {
        int numCursors = mManagedCursors.size();
        for (int i = 0; i < numCursors; i++) {
            ManagedCursor c = mManagedCursors.get(i);
            if (c != null) {
                c.mCursor.close();
            }
        }
        mManagedCursors.clear();
    }

    // Close any open search dialog
    if (mSearchManager != null) {
        mSearchManager.stopSearch();
    }

    getApplication().dispatchActivityDestroyed(this);
}

在这里,排序 可能@H_403_20@ 取决于您的活动设置方式以及调用是否super.onDestroy()会干扰后面的代码,可能 会很@H_403_20@ 重要。

最后,该声明Always call the superclass method first似乎没有足够的证据来支持它。更糟糕的是(对于该语句)以下代码摘自android.app.ListActivity

public class ListActivity extends Activity {

    ....

    @Override
    protected void onDestroy() {
        mHandler.removeCallbacks(mRequestFocus);
        super.onDestroy();
    }
    ....    
}

并且,来自android sdk中包含的LunarLander示例应用程序:

public class LunarLander extends Activity {

    ....

    @Override
    protected void onPause() {
        mLunarView.getThread().pause(); // pause game when Activity pauses
        super.onPause();
    }
    ....
}

:提供一种方案,super.onPause()在这种情况下,如果Activity开始使用,则必须延迟呼叫startActivityForResult(Intent)。使用setResult(...)after@H_403_20@ 设置结果super.onPause()将不起作用。后来,他在对答案的评论中对此进行了澄清。

:从逻辑上解释为什么让超类首先初始化其资源并最后破坏其资源的原因:

让我们考虑一下您下载的一个库,该库具有一个LocationActivity,其中包含提供位置的getLocation()函数。最有可能的是, 。您已经这样做了,因为您认为这很有道理。现在,在您的onDestroy中,您决定要将该位置保存在SharedPreferences中的某个位置。如果首先调用super.onDestroy,则在一定程度上调用后getLocation将返回空值,因为LocationActivity的实现会使onDestroy中的位置值无效。这个想法是,如果发生这种情况,您不会怪它。

他继续指出:如果子类与父类适当地隔离(就资源依赖而言),则super.X()调用不必遵循任何顺序规范。

在此页面上查看他的答案,以通读super.onDestroy()调用位置 确实@H_403_20@ 会影响程序逻辑的情况。

,以确保Android在您开始之前有机会做自己的工作尝试做一些依赖于已经完成的工作的事情。

。这样,如果Android清理了您的工作所依赖的内容,则您将首先完成工作。

返回除void以外的内容方法(onCreateOptionsMenu()等),有时您会链接到return语句中的超类,假设您没有专门执行需要强制特定返回值的操作。

总体而言,其他一切(如onActivityResult())都取决于您。首先,我倾向于链接到超类,但是除非遇到问题,否则稍后链接应该没问题。

这个话题

这是一个很好的模式[(Mark在上面建议的模式)],但是我发现了一些例外。例如,

也引起注意:

我只知道一种情况,需要超级调用的时间。 。否则,AFAIK在您调用它的时间没有区别。

确认调用Activity类的方法时,顺序(最有可能)不起作用。他还声称, 。但是,我不能证实这一点。

:说明为什么对超类 构造函数@H_403_20@ 的调用必须先于其他所有。我认为,这种解释不会增加所要提出的问题。

:信任, 但请@H_403_20@ 验证。此页面上的大多数答案都采用这种方法来查看该语句Always call the superclass method first是否具有逻辑依据。事实证明,事实并非如此。至少,不是在Activity类的情况下。通常,应该通读超类的源代码,以确定是否需要对超类的方法进行排序调用

其他 2022/1/1 18:13:38 有785人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶