【问题标题】:Activity life cycle methods : onPostResume significanceActivity生命周期方法:onPostResume意义
【发布时间】:2017-02-07 17:00:13
【问题描述】:

关于Activity的官方文档列出了7种生命周期方法。

onPostResume() 未被引用为生命周期方法。

但是我觉得这个方法很重要。

在生命周期中,当一个activity从隐藏到显示状态可见时,

onRestart()
onStart()
onResume()
onPostResume()

已按顺序调用。

我的代码sn-p:

package ravindra.projects.my_app_1;

import android.content.Intent;
import android.content.IntentFilter;
import android.os.PersistableBundle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import android.widget.TextView;


public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private EditText txtUserName;
    private EditText txtPassword;
    Button  loginButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("Ravi","Main OnCreate");
        txtUserName=(EditText) findViewById(R.id.username);
        txtPassword=(EditText) findViewById(R.id.password);
        loginButton =  (Button)  findViewById(R.id.login);
        loginButton.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        Log.d("Ravi", "Login processing initiated");
        Intent intent = new Intent(this,LoginActivity.class);
        Bundle bundle = new Bundle();
        bundle.putString("userName",txtUserName.getText().toString());
        bundle.putString("password",txtPassword.getText().toString());
        intent.putExtras(bundle);
        startActivityForResult(intent,1);
       // IntentFilter
    }
    public void onActivityResult(int requestCode, int resultCode, Intent resIntent){
        Log.d("Ravi back result:", "start");
        String result = resIntent.getStringExtra("result");
        Log.d("Ravi back result:", result);
        TextView txtView = (TextView)findViewById(R.id.txtView);
        txtView.setText(result);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("Ravi","Main Start");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("Ravi","Main ReStart");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("Ravi","Main Pause");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("Ravi","Main Resume");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("Ravi","Main Stop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("Ravi","Main OnDestroy");
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        Log.d("Ravi","Main PostResume");
    }

    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    }
}

通过跳过下面的方法来实现onPostResume() 不能达到目的吗?

onRestart(), onStart(), onResume()

如果我实现onPostResume(),实现这三种方法有什么好处?

onRestart(), onStart(), onResume()

【问题讨论】:

  • 有很多要解释的,最好的解释在这里:commonsware.com/Android/Android-5.8-CC.pdf 本书第303页,由@Commonsware 自己编写,此版本在CC 非商业许可下授权。
  • @OBX,在那里看不到onPostResume

标签: android android-activity android-lifecycle


【解决方案1】:

onPostResume :

在 Activity 恢复完成时调用(在 Activity 的 {@link #onResume} 有 被调用)。应用程序一般不会实现此方法; 它旨在让系统类在应用程序后进行最终设置 恢复代码已运行。

它会做以下事情

  1. 它将确保屏幕对用户可见,并将执行最后 为活动做准备。

  2. 删除所有待处理的帖子,其中包含代码“what” 这 消息队列。

  3. 检查所有片段是否已恢复并移动由管理的所有片段 控制器的 FragmentManager 进入恢复状态。

  4. 对由 控制器的 FragmentManager。

如果您检查它的生命周期虎钳,它的工作方式如下所示

  1. onResume() - 活动

  2. onResume() - 片段check third point as explained above

  3. onPostResume() - 活动

【讨论】:

  • 我还使用了 onPostResume() 方法在 FragmentTransaction 中提交片段,因为该方法保证在 Activity 恢复到其原始状态后被调用,这样我将避免 IllegalStateException 发生。
【解决方案2】:

onPostResume 主要保留给想要在任何子类完成恢复后完成某种设置的系统操作。

它有两个好处,(这可能会让你觉得它很重要)是用于执行操作你的嵌套片段也被恢复时应用程序保证对用户可见(在 onResume 期间可能还不可见)。

查看源代码时,方法名称可能会有点混乱,但如果您记录流程,您会看到发生了什么

  1. 活动恢复
  2. 片段简历
  3. onPostResume 在 Activity 中被调用

我会提醒任何未来的读者——如果你使用 onPostResume 来等待你的片段,调用一些 get 方法(例如),那么你的设计很糟糕,不可靠。相反,您应该从片段中获得回调模式,并让片段在准备好时将数据“发送”回活动

【讨论】:

  • 可能是 application 对用户可见,但在我的情况下,当调用 onPostResumeactivity 还不可见.
  • onSaveInstanceState 的问题是什么?如果您尝试在 onResume 中执行操作,例如恢复对话片段,那么您需要提交事务,这可能很危险,因为状态尚未恢复。
【解决方案3】:

在回答你的问题之前,让我们谈谈onPostResume() 根据安卓

onPostResume()

在 API 级别 1 中添加

void onPostResume ()

activity 简历完成时调用 (after onResume() has been called)。 应用程序一般不会实现此方法;它旨在让系统类在应用程序恢复代码运行后进行最终设置

所以正如他们所说,一旦活动恢复,它就会被调用。因此,如果您想在活动恢复后做某事,您可以使用此方法。但大多数情况下,我们在onResume() 中完成所有工作,例如开始动画、打开独占访问设备(例如相机)等,因此一旦恢复活动onPostResumed() 就会被调用。所以你不认为它与简历上的不同吗?因为在 onPostResume() 中根据 os 活动已经恢复。而对于 onPause 和 onStop()。它们是不同的。它们是当活动进入后台但尚未(尚未)被杀死并在您不再对用户可见时被调用。所以它们不同于onResume()onPostResume()

现在在依赖 onPostResume() 之前,你应该阅读这两件事 至于developers.android 1 - 应用程序通常不会实现此方法;它旨在让系统类在应用程序恢复代码运行后进行最终设置。 (但无论目的是什么,我们都可以将它用于我们的目的)。 2 - 检查此link。他说 onPostResume() 不是 ALWAYS 被调用的。他的案子是碎片(当然他们是在一个活动的人身上)。 以下是回复, 该问题在 API 级别 16 和支持库 rev 9 中完全解决。 应该使用新方法“FragmentActivity.onResumeFragments()”。

所以他们中的一些人在依赖这种方法时遇到了问题,所以这取决于你。

【讨论】:

    【解决方案4】:

    onPostResume() 未被引用为生命周期方法。

    但我觉得这个方法很重要。

    很可能你的感觉是错误的。我对为什么会这样的回答有点冗长而且有点抽象。

    抽象(但重要)部分

    通常各种onPreXyzonPostXyz(又名onBeforeXyzonAfterXyz)方法试图使基类对子类的扩展开放,但仍保留一些重要的行为方面。假设您正在设计自己的基类,并且您有一个生命周期事件“Xyz”,并且您的默认处理行为如下:

    1. 在进行任何其他处理之前进行一些初始化
    2. 对事件进行实际处理,包括可自定义的逻辑
    3. 当所有可自定义的处理完成后,执行一些整理逻辑

    现在假设您正在制作类似Activity 类的东西 - 一个具有一些逻辑位的基类,并且会被大量继承,可能具有很深的继承层次。现在您应该考虑关于基类中的逻辑将在何处(何时)执行子类逻辑。这里重要的棘手部分是您希望您的子类将它们的附加逻辑放在步骤 #2 周围(即在 #1 之后和 #3 之前)。您无法使用简单的虚方法轻松实现此目标,因为子类可以在调用 super 之后将其逻辑放在 #3 之后或(很少)在 super 调用之前,即在 #1 之前。那你会怎么做? Template method pattern 来救援。您可以通过以下方式组织代码

    class Activity {
        public final void performXyz(XyzEventData eventData) {
           onPreXyz(eventData);
           onXyz(eventData);
           onPostXyz(eventData);
        }
    
        protected void onPreXyz(XyzEventData eventData) {
           // put you logic from step #1 here
        }
    
        protected void onXyz(XyzEventData eventData) {
           // put you logic from step #2 here
        }
    
        protected void onPostXyz(XyzEventData eventData) {
           // put you logic from step #3 here
        }
    }
    

    因此,您有一个外部入口点 performXyz,当 Xyz 事件发生时,无论上下文生成生命周期事件,它都会调用该入口点,并将该事件在内部分派给 3 个不同的方法,以执行某些执行顺序。通常,您将所有代码放在“main”onXyz 方法内的子类中,除非您有充分的理由将其放在另外两个中的一个中,即您希望您的类也被子类化并且您希望确保一些执行命令。

    还有几点值得注意:

    1. 入口点方法performXyzfinal(即非虚拟)。通过这种方式,您可以确保没有人可以覆盖它并破坏您的执行顺序执行逻辑。

    2. 基类甚至可能离开onPreXyzonPostXyz 通过将其步骤#1 和#3 逻辑直接放入performXyz,方法为空。但是,如果基类的设计者期望可能的深层继承层次结构,其中一些中间子类将成为许多其他更深层子类的基类(例如Layer supertype),可能需要相同的执行顺序强制功能,它使无论如何,在基类中提供这样的方法是有意义的。

    3. onPreXyzonPostXyz 方法之一可能是 如果您的案例不需要 3 步执行,则完全省略 分离和两步就足够了。这就是 Android 中经常发生的情况:onPostXyz 方法比 onPreXyz 多得多,但 AsyncTask 似乎是一个明显的例外,同时具有这两种方法。

    深入了解 Android(以及 onPostResume)

    那么经过这么长的介绍,Android 是如何为onPostResume 使用这种方法的呢?如果您查看Activity.onPostResume 处的代码,您会注意到它在基类中做的事情很少,并且与 UI 内容密切相关,并且可能期望所有数据结构都已完全准备好。这当然不足为奇。

    更有趣的是它是如何在子类中使用的。极少数覆盖之一是来自 v4 支持库的 FragmentActivity,它为旧设备提供了向后移植的“片段”功能。 FragmentActivity.onPostResume 包含恢复子片段的逻辑。您可能会注意到,在标准 Activity 类中,与恢复片段类似的逻辑被直接放入 performResume 方法中,在 mInstrumentation.callActivityOnResume(this);onPostResume(); 调用之间,所以它似乎是我之前的抽象描述中步骤 #3 的一部分放入调用者代码。显然FragmentActivity 不能在Activity.performResume 中添加任何新代码,以确保在活动恢复完成后执行。因此,它将逻辑置于覆盖的FragmentActivity.onPostResume 中,并以这种方式保留了在活动已经恢复后应该恢复片段的相同语义。另请注意,在ActivityFragmentActivity 类中明确保留此语义这一事实表明,这是最好的方式。因此,如果您的代码实际上使用了片段,您最好不要将广泛的逻辑放入您的 onPostResume 中,否则可能会发生不好的事情(不确定到底是什么)。

    【讨论】:

    • 我真的不明白为什么这个答案被否决了。至少在投票时写下你的理由。仅投反对票,对任何人都没有帮助。他/她努力写一个答案;你努力写一个理由..
    • onSaveInstanceState 的问题是什么?如果您尝试在 onResume 中执行操作,例如恢复对话片段,那么您需要提交事务,这可能很危险,因为状态尚未恢复
    • @kingston,我认为我无法通过此描述理解您的问题。 onSaveInstanceStateonResume 有什么关系?它在生命周期的一个完全不同的部分被调用。如果您有问题,您应该在 SO 上创建一个新问题,以便每个人都可以回答,而不是对模糊相关问题的答案发表相同的评论。
    【解决方案5】:

    在使用活动生命周期的日志和覆盖方法后,我得出以下结论: 如果您想在恢复片段后(加载片段后)在父活动中执行任何特定任务,此方法非常有用....

    我使用/尝试了以下代码 sn-ps 来得出这个结论:

    在父活动中:

    //postResumemethod
     @Override
        protected void onPostResume() {
            super.onPostResume();
            Log.v("testPostResume","reached_postResume") ;
    
        }
    
    In called Fragment :
    
    //On ResumeMethod
     @Override
        public void onResume() {
            super.onResume();
    
            Log.v("testStartFragment","reached_Startfragment") ;
        }
    

    这是我的日志: V/testStartFragment:达到_Startfragment v/testPostResume:reached_postResume


    我们可以清楚的看到post resume是在Fragment的onResume方法执行后调用的。所以在调用/加载片段之后,如果你想在活动中执行任何代码(加载片段后通过活动的任何任务)你可以这样做

    我希望这可以澄清查询

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-15
      • 1970-01-01
      • 1970-01-01
      • 2013-04-06
      • 2018-07-18
      • 2012-09-21
      • 2019-01-05
      • 2013-07-10
      相关资源
      最近更新 更多