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


89

我刚浏览了Android开发者网站,刷新了活动生命周期,在每个代码示例中,超类方法旁边都有一条注释,上面写着“始终先调用超类方法”。

虽然这在创建半周期(onCreate,onStart和onResume)中是有意义的,但对于销毁半周期的正确过程是什么,我还是有些困惑:onPause,onStop,onDestroy。

首先销毁实例专用资源,然后销毁实例专用资源可能依赖的超类资源,这是有道理的,而不是相反。我想念什么?

编辑:由于人们似乎对这个问题的意图感到困惑,所以我想知道以下哪个是正确的?为什么?

1,谷歌建议

    @Override
    protected void onStop() {
      super.onStop();  // Always call the superclass method first

      //my implementation here
    }

2.另一种方式

    @Override
    protected void onStop() {
       //my implementation here

       super.onStop();  
    }

1
我在第二个营地了解关闭方法。我在第一营了解启动方法。
danny117

1
这就是重点。只是不明白如何将方法1用于关机方法才有意义。
Anudeep Bulla 2013年

Answers:


107

在销毁实例特定资源可能依赖的超类资源之前,先销毁实例特定资源是合理的,而不是相反。但是这些评论暗示了另外的观点。我想念什么?

我认为:没有一件事情。

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

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

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

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

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);
}

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

最后,该声明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();
    }
    ....
}

总结和值得一提:

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

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

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

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

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

根据马克的回答

重写的方法是组件创建的一部分(onCreate(),onStart(),onResume()等),您应该作为第一条语句链接到超类,以确保Android在您开始之前有机会做自己的工作尝试做一些依赖于已经完成的工作的东西。

重写的方法是组件破坏的一部分(onPause(),onStop(),onDestroy()等),您应该首先完成工作并最后链接到超类。这样,如果Android清理了您的工作所依赖的内容,则您将首先完成工作。

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

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

Bob Kerns这个话题

这是一个很好的模式[(Mark在上面建议的模式)],但是我发现了一些例外。例如, 除非我将其放在超类的onCreate()之前,否则我想应用到PreferenceActivity的主题将不会生效。

用户Steve Benett也引起注意:

我只知道一种情况,需要超级调用的时间。如果要更改主题或显示的标准行为,例如onCreate,则必须先调用super才能看到效果。否则AFAIK在您调用它的时间没有区别。

用户Sunil Mishra确认调用Activity类的方法时,顺序(最有可能)没有起作用。他还声称,首先调用超类方法被认为是最佳实践。但是,我不能证实这一点。

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

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


2
哇。感谢您的指导。这和@Sherif的答案都提供了重要的上下文。如果任何人都可以总结此页面上的答案,则将其标记为已接受。请包括:1.此页面上的答案。2. @ Philip在此页面上的答案3. @ CommonsWare在此页面上的答案4. 我希望进行此讨论 ,但我不希望您的精彩回答
Anudeep Bulla 2013年

你好 您能否总结一下,因为@Sherif不想这么做?
Anudeep Bulla 2013年

@AnudeepBulla嗨,Anudeep,给我直到明天。我将在回答中添加相关材料,并在此处给您留言。
Vikram

@AnudeepBulla我在上面添加了摘要。如果我错过了任何事情,请告诉我。
Vikram

@Vikram是TL; DR。那调用onDestroyonStoplast是一个更安全的默认值,并且在onPause某些情况下,事情变得更加棘手?您可以先添加吗?我很想自己编辑答案,但不确定此摘要是否正确。
Blaisorblade

12

因为(您说)首先调用super onCreate是有意义的:考虑一下。

当我要创建时,我的超级创建其资源>创建我的资源。

反之:(有点像栈)

当我想破坏时,我破坏了我的资源>我的超级破坏了他的资源。


从这个意义上讲,它适用于任何两个函数(onCreate / onDestroy,onResume / onPause,onStart / onStop)。自然,onCreate将创建资源,而onDestroy将释放这些资源。顺便说一句,相同的证明适用于其他夫妇。

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

如果上述说法合理,请考虑我们随时都有遵守上述概念的活动。如果我想扩展此活动,则由于相同的确切参数,我可能会有相同的感觉并遵循相同的顺序。

通过归纳,任何活动都应做同样的事情。这是一个必须遵循以下规则的活动的良好抽象类:

package mobi.sherif.base;

import android.app.Activity;
import android.os.Bundle;

public abstract class BaseActivity extends Activity {
    protected abstract void doCreate(Bundle savedInstanceState);
    protected abstract void doDestroy();
    protected abstract void doResume();
    protected abstract void doPause();
    protected abstract void doStart();
    protected abstract void doStop();
    protected abstract void doSaveInstanceState(Bundle outState);
    @Override
    protected final void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        doCreate(savedInstanceState);
    }
    @Override
    protected final void onDestroy() {
        doDestroy();
        super.onDestroy();
    }
    @Override
    protected final void onResume() {
        super.onResume();
        doResume();
    }
    @Override
    protected final void onPause() {
        doPause();
        super.onPause();
    }
    @Override
    protected final void onStop() {
        doStop();
        super.onStop();
    }
    @Override
    protected final void onStart() {
        super.onStart();
        doStart();
    }
    @Override
    protected final void onSaveInstanceState(Bundle outState) {
        doSaveInstanceState(outState);
        super.onSaveInstanceState(outState);
    }
}

最后,如果您的活动称为AnudeepBullaActivity扩展BaseActivity,然后又想创建SherifElKhatibActivity一个扩展您的活动怎么办?我应该以什么顺序调用这些super.do函数?最终是同一回事。


至于你的问题:

我认为Google的意图是告诉我们:无论在哪里,都请致电超级。当然,通常应在一开始就将其命名。Google当然拥有最聪明的工程师和开发人员,因此他们可能在隔离超级调用而不干扰子调用方面做得很好。

我尝试了一下,创建一个由于将何时调用何时调用super而导致崩溃的活动可能并不容易(因为它是Google,我们试图证明是错误的)。

为什么?

这些函数所做的任何事情实际上都是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);
}

mManagedCursors和mManagedDialogs以及mSearchManager都是私有字段。并且任何公共/受保护的api都不会受到此处所做操作的影响。

但是,在API 14中,添加了dispatchActivityDestroyed,以将onActivityDestroyed调度到已注册到您的应用程序的ActivityLifecycleCallbacks。因此,任何依赖于ActivityLifecycleCallbacks中的某些逻辑的代码都会根据调用超级对象的时间而产生不同的结果。例如:

创建一个应用程序类来计算当前正在运行的活动的数量:

package mobi.shush;

import android.app.Activity;
import android.app.Application;
import android.app.Application.ActivityLifecycleCallbacks;
import android.os.Bundle;

public class SherifApplication extends Application implements ActivityLifecycleCallbacks {
    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(this);
    }
    public int getCount() {
        return count;
    }
    int count = 0;
    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        count++;
    }
    @Override
    public void onActivityDestroyed(Activity activity) {
        count--;
    }
    @Override
    public void onActivityPaused(Activity activity) {}
    @Override
    public void onActivityResumed(Activity activity) {}
    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState)           {}
    @Override
    public void onActivityStarted(Activity activity) {}
    @Override
    public void onActivityStopped(Activity activity) {}
}

以下内容可能没有意义,也不是一个好的实践,但这只是为了证明一个观点(可能会发现更实际的情况)。创建完成时和最后一个活动时应进入GoodBye活动的MainActivity:

@Override
protected void onDestroy() {
    super.onDestroy();
    if(((SherifApplication) getApplication()).getCount() == 0) {
        //i want to go to a certain activity when there are no other activities
        startActivity(new Intent(this, GoodBye.class));
    }
}

如果在onDestroy的开头调用super.onDestroy,则会启动GoodBye活动。如果在onDestroy结束时调用super.onDestroy,则不会启动GoodBye活动。

当然,这也不是最佳示例。但是,这表明Google在这里有些混乱。其他任何变量都不会影响您应用程序的行为。但是,将这些分派添加到onDestroy会导致父控件以某种方式干扰您的子类。

我说他们也因为不同的原因而陷入困境。他们(在api 14之前)不仅在超级调用中涉及到final和/或private,而且还调用了不同的内部函数(private),这些内部函数实际上随后分派了onPause ...函数。

例如,performStopfunction是被调用的函数,该函数又调用onStop函数:

final void performStop() {
    if (mLoadersStarted) {
        mLoadersStarted = false;
        if (mLoaderManager != null) {
            if (!mChangingConfigurations) {
                mLoaderManager.doStop();
            } else {
                mLoaderManager.doRetain();
            }
        }
    }

    if (!mStopped) {
        if (mWindow != null) {
            mWindow.closeAllPanels();
        }

        if (mToken != null && mParent == null) {
            WindowManagerGlobal.getInstance().setStoppedState(mToken, true);
        }

        mFragments.dispatchStop();

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

        synchronized (mManagedCursors) {
            final int N = mManagedCursors.size();
            for (int i=0; i<N; i++) {
                ManagedCursor mc = mManagedCursors.get(i);
                if (!mc.mReleased) {
                    mc.mCursor.deactivate();
                    mc.mReleased = true;
                }
            }
        }

        mStopped = true;
    }
    mResumed = false;
}

请注意,他们在此函数中的某个位置调用了Activity的onStop。因此,他们可能还把所有代码(包括在super.onStop中)放在对onStop的调用之前或之后,然后仅使用空的onStop超级函数通知有关onStop的子类,甚至不添加SuperNotCalledException或检查此调用。

为此,如果他们在performDestroy中将此分派调用到ActivityLifeCycle,而不是在super.onDestroy的末尾调用它,则无论何时调用超级,我们的活动行为都将是相同的。

无论如何,这是他们要做的第一件事(有点错误),并且仅在API 14中。


问题从来都不是为什么最后调用super.onDestroy()才有意义。我喜欢你的图书馆例子。正是我也想传达的内容。我完全同意在破坏半个循环的最后一刻调用超级方法,就像在堆栈中一样,以防止意外丢失数据。问题是在上述前提下,为什么Google坚持首先调用超级方法?我之所以问这个问题,是因为我认为也许我和貌似您也可能完全不同。干杯
Anudeep Bulla 2013年

哦,我没有看到Google的建议和另一种方式:p!听着,我将尝试创建一个活动,如果您先调用onDestroy将会崩溃。您也应该尝试一下。干杯
Sherif elKhatib

@AnudeepBulla,您可以检查我的编辑。而且,您可以停止尝试。super.on可能永远不会使您的活动崩溃。
Sherif elKhatib 2013年

哇。感谢您的指导。这和@User的答案都提供了重要的上下文。如果任何人都可以总结此页面上的答案,则将其标记为已接受。请包括:1.此页面上的答案。2. @ Philip在此页面上的答案3. @ CommonsWare在此页面上的答案4. 我希望进行此讨论 ,但我不希望您的精彩回答
Anudeep Bulla 2013年

@AnudeepBulla不客气。我不确定我们将如何决定谁发表最终论文。
Vikram 2013年

1

从Java的角度来看,这是解决这种混乱的方法:

为什么this()和super()必须是构造函数中的第一条语句?

需要在子类的构造函数之前调用父类的构造函数。这将确保,如果您在构造函数中的父类上调用任何方法,则该父类已经正确设置。

您想要做的是,将args传递给super构造函数是完全合法的,您只需要在执行操作时内联构造这些args,或者将它们传递给构造函数,然后将它们传递给super即可:

public MySubClassB extends MyClass {
        public MySubClassB(Object[] myArray) {
                super(myArray);
        }
}

如果编译器未强制执行此操作,则可以执行以下操作:

public MySubClassB extends MyClass {
        public MySubClassB(Object[] myArray) {
                someMethodOnSuper(); //ERROR super not yet constructed
                super(myArray);
        }
}

它表明,实际上,子字段必须在最高级别之前被初始化!同时,java要求通过专门化super构造函数的参数来“防御”我们专门化类。

如果父类具有默认构造函数,则编译器会自动为您插入对super的调用。由于Java中的每个类都继承自Object,因此必须以某种方式调用对象构造函数,并且必须首先执行它。编译器自动插入super()可以实现这一点。强制super出现在最前面,强制以正确的顺序执行构造函数主体,即:对象->父->子-> ChildOfChild-> SoOnSoForth

(1)仅检查super是第一条语句不足以防止该问题。例如,您可以输入“ super(someMethodInSuper());”。在您的构造函数中。即使super是第一个语句,这也会尝试在构造超类之前访问该方法。

(2)编译器似乎执行了另一种检查,其本身足以防止此问题。消息为“在调用超类型构造函数之前无法引用xxx”。因此,不必检查super是第一条语句

请浏览此http://valjok.blogspot.in/2012/09/super-constructor-must-be-first.html


我完全理解您在那摆什么。您首先调用超类构造函数,因为它们可能会初始化子级可能需要的资源。最后破坏者说,'因为你不想抹掉所有父母的本地资源,使他们毫无意义。这正是我的观点。而且由于onPause,onStop和onDestroy的任务是保存状态信息,或多或少地使资源可供GC使用(因此在某种意义上销毁了它们),我认为它们类似于析构函数,因此认为最后调用它们是有意义的。没有?
Anudeep Bulla 2013年

您在上面所说的一切正是我说“在创建半周期中首先调用超级方法才有意义”时的意思。我很担心,在销毁半周期方法的情况下感到困惑,这似乎更类似于析构函数。欢呼声
Anudeep Bulla 2013年

1

要记住的最重要的事情是super.onPause()隐式调用setResult(Activity.RESULT_CANCELED)。但是setResult只能调用一次,所有后续调用都将被忽略。因此,如果您想将任何一种结果推回上级活动,则必须在致电之前打电话给setResult自己。据我所知,那是最大的陷阱。super.onPause()


哇,这似乎很重要。因此,在某些情况下,您肯定必须延迟对super方法的调用。谢谢。
Anudeep Bulla

super.onPause() implicitly calls setResult(Activity.RESULT_CANCELED)。你能说你从哪里得到的吗?
Vikram

我很困惑。实际上是finish()调用setResult,而super.onBackPressed()调用finish()。因此,必须在super.onBackPressed()之前调用setResult。我不确定在任何情况下super.onPause()都可能导致setResult被调用,但是我不想冒险。
菲利普·谢德

1

两者都是正确的IMO

根据文档

派生类必须调用此方法的超类的实现。如果不这样做,将引发异常。

Super 文档明确指出时应始终调用方法。

但是,您可以选择何时调用super方法。

看源 onPause

protected void onPause() {
    getApplication().dispatchActivityPaused(this);
    mCalled = true;
}

因此,无论调用之前还是之后。你应该很好。

但是为了获得最佳实践,您应该首先调用它。

我主要推荐它作为一种保护机制:如果有异常,则 super实例方法将已经被调用。

同样,将这些调用放在第一行将帮助您避免将来犯错误,例如删除方法中的代码和意外删除对超类的调用。


很抱歉,这个问题在第一时间还不是很清楚,但现在请看一下。
Anudeep Bulla 2013年

@AnudeepBulla这就是我向您解释的内容。您可以使用它们之一。两者均有效。
Sunil Mishra 2013年

据我了解,方法onPause,onStop和onDestroy的自定义实现不是严格必需的。没有这些,我已经制作了很多应用。那么,应该始终调用Super方法是什么意思?即使没有覆盖,它们也会被隐式调用。我也知道两者都可以。我想知道为什么文档说super应该首先被调用。如果问题仍然不明显,当您说“但是为了最佳实践,您应该先调用它”时,请解释一下原因吗?
Anudeep Bulla 2013年

如果您不重写,则从中调用方法,Base Class但是如果您重写,则需要调用super将要拥有的其他方法android.app.SuperNotCalledException
Sunil Mishra

1
您似乎误会了。问题不在于是否致电。如您所指出的,如果您要覆盖它们,则必须这样做。问题是,什么时候?
Anudeep Bulla 2013年

1

您说Google建议使用方法1,但是著名的Android框架工程师Dianne Hackborn建议不要使用Google Forum Link

这使得直观的感觉来调用超类的最后破坏的一个实例的onPause,的onStop的onDestroy方法和第一创建与方法的实例的onCreate,的onResume在onStart


指向Dianne Hackborn帖子的链接很重要,并且可以确认这种模式。
Nick Westgate 2015年

0

需要回调的上级才能在系统内部将Activity置于正确的状态。

假设您开始活动,并且系统调用了onCreate。现在,您可以覆盖它并例如加载您的布局。但是由于系统流程的原因,您必须调用super,以便系统可以继续执行标准过程。这就是为什么如果您不调用它将引发异常的原因。

这与onCreate中的实现无关。它只是系统的重要组成部分。如果没有ANR,您可能在任何回调中都有一个无限循环,而Activity将陷入该回调中。因此,系统知道回调何时终止,然后调用下一个回调。

我只知道一种情况,需要超级调用的时间。如果要更改主题或显示的标准行为,例如onCreate,则必须在调用super之前先进行更改以查看效果。否则,AFAIK在您调用它的时间没有区别。

但是,如果没有充分的理由让系统做最好的事情,最好将super放在回调的第一行,然后再加上代码。


onCreate中的序列似乎可以理解。销毁方法会发生什么?说onStop。假设我的onStop实现使用了super方法释放的某些资源(如果被调用),那么在实现之后调用super方法是有意义的。
Anudeep Bulla 2013年

理想情况下,应该是这样。我们的活动将始终具有超类所拥有的资源,以及更多资源。在大多数情况下,与我的活动无关的资源可能取决于常见的超类资源。首先处理我的资源,然后调用超类来处理通用资源,这才有意义。Google为什么然后说我们先“应该”调用超类方法?
Anudeep Bulla 2013年

您在谈论什么资源,您可以在onCreate而不是onDestroy中访问哪些资源?
史蒂夫·贝内特

我没有用例。我只是想知道,它随着OOP样式的变化而变化。在实现之前,将超级类构造函数首先调用,在实现之后将其称为最后函数,对吗?onPause,onStop和onDestroy并不是严格的析构函数,但是它们倾向于做相同的事情,对吗?Atleast onDestroy且主要在onStop上..不?
Anudeep Bulla 2013年

以状态更改方式查看回调,而不是以构造函数/析构函数的形式查看。每个回调都需要它,例如,创建(准备使用)/销毁(您进行交互的最后机会)或将其放在前台/后台。那里有回调,您可以控制系统流程中的资源。系统仅检查它处于哪种状态并相应地进行处理。您使用的资源与系统控制的资源是彼此独立的,并且不会有交集。
史蒂夫·贝内特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.