【问题标题】:Android: Scenario where onPause is called but not onStop?Android:调用onPause但不调用onStop的场景?
【发布时间】:2015-09-17 15:53:28
【问题描述】:

我试图了解 onPause 和 onStop 之间的区别。

我已经阅读了所有不同的论坛,但我仍然不清楚它们之间的区别。我创建了一个简单的应用程序来尝试测试何时调用哪个方法。为此,我只是在每个方法中放置了记录器。

来自我的试验-

  1. 弹出窗口不调用任何一种方法
  2. 切换到另一个活动会调用这两种方法
  3. 下拉通知栏不会调用任何方法

我只看到这两种方法都被快速连续调用,或者根本没有被调用。 我试图找到 onPause 被调用但 onStop 没有被调用的场景。

目的是了解是否需要定义 onPause。如果只调用 onPause 的场景如此罕见,那么为 onPause 编写单独的代码甚至没有意义。不应该写 onStop 就足够了吗?

public class LifecycleActivity extends ActionBarActivity {

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("Rachit", "In Destroy Method");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lifecycle);
        Log.d("Rachit", "In Create Method");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("Rachit", "In Start Method");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("Rachit", "In Resume Method");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("Rachit", "In Pause Method");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("Rachit", "In Restart Method");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("Rachit", "In Stop Method");
    }
}

【问题讨论】:

  • 弹出窗口的意思是对话框还是别的什么?当我调用对话框时,我的活动进入暂停状态。

标签: android


【解决方案1】:

官方的 Android 开发者页面你可以看到与这两种活动状态相关的所有信息

onPause() (http://developer.android.com/training/basics/activity-lifecycle/pausing.html)

当系统为您的活动调用 onPause() 时,从技术上讲 表示您的活动仍然部分可见,但通常是 指示用户正在离开活动,并且很快就会离开 进入停止状态。您通常应该使用 onPause() 回调 到:

停止可能消耗 CPU 的动画或其他正在进行的操作。 提交未保存的更改,但前提是用户期望此类更改 他们离开时永久保存(例如草稿电子邮件)。发布 系统资源,例如广播接收器、传感器句柄 (如 GPS),或任何可能影响电池寿命的资源,而您 活动已暂停,用户不需要它们。

一般情况下,您不应该使用 onPause() 来存储用户更改(例如 输入表格的个人信息)永久存储。这 只有当您应该将用户更改持久保存到其中的永久存储时 onPause() 是当您确定用户期望更改为 自动保存(例如在起草电子邮件时)。但是,您应该避免 在 onPause() 期间执行 CPU 密集型工作,例如写入 数据库,因为它可以减慢可见的过渡到下一个 活动(您应该改为执行重负载关闭操作 在 onStop()) 期间。

您应该保持在 onPause() 方法中完成的操作量 相对简单,以便快速过渡到 如果您的活动实际上已停止,用户的下一个目的地。

注意:当您的 Activity 暂停时,Activity 实例会保留 驻留在内存中,并在活动恢复时被调用。你 不需要重新初始化在任何过程中创建的组件 导致 Resumed 状态的回调方法。

onStop() (http://developer.android.com/training/basics/activity-lifecycle/stopping.html)

当您的活动收到对 onStop() 方法的调用时,它不是 更长的可见性并且应该释放几乎所有不可见的资源 用户不使用时需要。一旦你的活动停止, 如果需要恢复系统,系统可能会破坏实例 记忆。在极端情况下,系统可能会简单地杀死您的应用程序 进程不调用活动的最终 onDestroy() 回调,所以 使用 onStop() 释放可能泄漏的资源很重要 记忆。

虽然 onPause() 方法在 onStop() 之前被调用,但你应该 使用 onStop() 执行更大、更占用 CPU 的关机 操作,例如将信息写入数据库。

当您的活动停止时,活动对象保持驻留在 记忆并在活动恢复时被调用。你不需要 重新初始化在任何回调期间创建的组件 导致 Resumed 状态的方法。该系统还跟踪 布局中每个视图的当前状态,所以如果用户 在 EditText 小部件中输入文本,该内容被保留,因此您 无需保存和恢复。

注意:即使系统在停止时破坏了您的活动,它 仍然保留 View 对象的状态(例如 EditText)在一个Bundle(一个键值对的blob)中并在以下情况下恢复它们 用户导航回活动的同一实例(下一个 本课更多地讨论了使用 Bundle 将其他状态数据保存在 如果您的活动被销毁并重新创建)。

【讨论】:

  • 是的,但我还没有找到 onPause 被调用但 onStop 没有被调用的实例。如果它们总是一起调用,那么只使用一种方法并在其中保存数据或释放资源不是更有意义吗?
  • 只有当activity不完全可见时才会调用onStop方法,而当activity仍然可见但一直在后台时调用onPause方法。例如,当您显示一个对话框时。 Activity Dialog的后面是onPause,但是如果你打开一个新的Activity,是通过onPause和onStop的方法传递的@Rachit
  • 这就是问题所在。对话框不会调用 onPause。我试过获取对话框,但即使这样 onPause 也没有被调用。
  • 你能给我看一段你的代码来帮助更好吗?
  • @Rachit 如果您使用DialogActivity,则只会调用onPause()。看看@Ishwar Verma 提供的答案。
【解决方案2】:

当您从当前活动启动 DialogActivity,然后调用当前活动的 onPause() 并在当前 Activity 启动后调用 onResume() 时,会发生这种情况。

欲了解更多信息,请参阅Developer Docs。

【讨论】:

  • Android 框架工程师的 FWIW this answer 是一本很好的读物。 Ishwar Verma 的回答中的DialogActivity 是一个应用对话框样式的活动,所以基本上它是一个看起来像对话框的活动。
【解决方案3】:

后来我想通了,但忘了在这里发布我的答案。

我注意到 onPause() 被调用但没有立即调用 onStop() 的情况是当我在手机上打开另一个应用程序时收到来自另一个应用程序的通知。

例如,假设您目前在手机上运行 Facebook。如果您收到来自 WhatsApp 的通知(在弹出对话框中),您的 Facebook 活动将暂停。如果您在此期间关闭 WhatsApp 弹出窗口,Facebook 活动将恢复。另一方面,如果您从弹出消息中打开 WhatsApp,您的 Facebook 活动将被停止。

【讨论】:

  • 兄弟,你应该都在上面。
  • 另一种情况是在多窗口模式下打开两个应用程序。当用户焦点在 App1 上时,App2 将处于 onPause 状态。
【解决方案4】:

当我们从当前 Activity 启动对话 Activity 时,只会调用 onPause()。 例如:假设我们有活动 A 和 B。现在活动 B 是对话活动,活动 A 是正常活动。当我们从活动 A 开始活动 B 时,将调用活动 A 的 onPause() 并调用活动 B 的onCreate()、onStart() 和 onResume()。请查看下面的 url 以获取示例代码 sample code

【讨论】:

    【解决方案5】:

    活动 A --> 活动 B 如果 B 是透明的,将调用 A' onPause 但不会调用 onStop。

    【讨论】:

      【解决方案6】:

      还有另一种方法可以做到这一点。 让我们假设您的活动启动模式是单任务并从中创建通知并触发它并再次调用相同的待处理意图,然后 onresume 将被称为 post to on pause。

      public class MainActivity extends AppCompatActivity {
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              sendNotification();
          }
      
          private final static String TAG = "TestOne";
      
          public  void sendNotification(){
              NotificationCompat.Builder mBuilder =
                      new NotificationCompat.Builder(this);
      
          //Create the intent that’ll fire when the user taps the notification//
      
          Intent i = new Intent(MainActivity.this, MainActivity.class);
          PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, i, 0);
      
      
          mBuilder.setContentIntent(pendingIntent);
      
          mBuilder.setSmallIcon(R.mipmap.ic_launcher);
          mBuilder.setContentTitle("My notification");
          mBuilder.setContentText("Hello World!");
      
          NotificationManager mNotificationManager =
      
                  (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
      
          mNotificationManager.notify(001, mBuilder.build());
      
      } 
      

      清单:

          <activity android:name=".MainActivity"
              android:launchMode="singleTask">
              <intent-filter>
                  <action android:name="android.intent.action.MAIN" />
      
                  <category android:name="android.intent.category.LAUNCHER" />
              </intent-filter>
          </activity>
          <activity android:name=".Main2Activity"></activity>
      

      【讨论】:

        【解决方案7】:

        onPause()一个activity的方法是当你接到电话时调用。否则在很多情况下onPause() 总是与onStop() 通话。例如当你按下主页按钮时,调用另一个意图,更像是当你的活动在后台时。

        【讨论】:

        • 当我从命令行发出 gsm call 12345 时,不知何故 onPause 不会被调用。
        【解决方案8】:

        我的测试用例结果:

        对于以下两个活动,当从MainActivity 开始C4_SecondActivity 时,对于MainActivity,它的onPause 被调用但不是onStop。

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity
            android:name=".C4_SecondActivity"
            android:label="@string/title_activity_c4__second"
            android:theme="@style/Theme.AppCompat.Dialog">
        </activity>
        

        【讨论】:

          【解决方案9】:
          Whenever we do Split window than onPause will be called alone 
          In Split window onStop will not be Called.
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-10-08
            • 2023-03-23
            • 1970-01-01
            • 2017-03-17
            相关资源
            最近更新 更多