【问题标题】:Android: OnDestroy isn't called when I close the app from the recent apps buttonAndroid:当我从最近的应用程序按钮关闭应用程序时,不会调用 OnDestroy
【发布时间】:2017-01-19 14:57:59
【问题描述】:

当我们按下这个按钮时

我们看到我们没有关闭的应用程序,像这样

但是当我们想从这个屏幕(下图)关闭应用程序时,不会调用 onDestroy() 方法,但是应用程序会关闭。当应用程序以这种方式关闭时,我需要调用 onDestroy() 。我该怎么做?

【问题讨论】:

  • 有很多场景不会调用onDestroy()。不要依赖onDestroy()。如果它被调用,请随意使用它来乐观地清理事物。但是,您的应用需要能够处理在任何组件(ActivityService)上未被调用的 onDestroy()
  • @CommonsWare 所以我必须创建服务吗?
  • 这样清除应用,相当于杀死桌面上的一个进程。你的应用会死在原地。

标签: java android ondestroy close-application


【解决方案1】:

如 Android 文档中所述,不能保证在退出应用程序时会调用 onDestroy()

“在某些情况下,系统会简单地杀死 Activity 的宿主进程而不调用此方法”

https://developer.android.com/reference/android/app/Activity.html#onDestroy%28%29

相反,您可以创建一个服务,当您的活动在其中运行的任务被销毁时,该服务将收到通知。

创建服务类:

public class ClosingService extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);

        // Handle application closing
        fireClosingNotification();

        // Destroy the service
        stopSelf();
    }
}

在清单中声明/注册您的服务(在应用程序标签内,但在任何活动标签外):

<service android:name=".services.ClosingService"
             android:stopWithTask="false"/>

指定stopWithTask="false" 将导致从进程​​中删除任务时在您的服务中触发onTaskRemoved() 方法。

在调用stopSelf() 销毁服务之前,您可以在此处运行关闭应用程序逻辑。

【讨论】:

  • 我想在应用关闭并且我们没有在应用中按下按钮时发送通知
  • 使用 onDestroy() 在您的应用关闭时收到通知是行不通的,因为应用由服务、接收器、后台任务、活动等组成。例如,一个音乐播放应用程序的所有 Activity 都被销毁,可能不会关闭,因为它可能还有一个音乐播放服务也在运行。
  • 还有这几行服务代码在manifestandroid:enabled="true" android:exported="true" 是对的吗?
  • 已导出意味着该服务将可供其他应用程序使用,您希望保留/将其设置为 false。已启用设置为 true 以便启用服务:)
  • 对我来说似乎没有触发,没有错误,只是不起作用
【解决方案2】:

您应该阅读一些有关 Activity 生命周期的信息。 onDestroy 方法有一件事,它不会一直被调用。你不能依赖它。

请说明您想要达到的目标,我会尽力提供更好的解决方案。

建议

所以,如果我的理解正确,我可以建议一件事。启动一个Service,它将每 N 秒触发一次LocalBroadcast(这对系统来说并不是很重)。在Activities 中注册并BroadcastReceiver 观看此广播。这样,您将获得truefalse,具体取决于是否有任何BroadcastReceiver 可以捕获您的LocalBroadcast。如果没有接收者,则检查一些 SharedPreferences 值,该值指示是否按下了 Button

【讨论】:

    【解决方案3】:

    比使用绑定服务更有效的方法是在应用程序中使用活动生命周期回调。尽管接受的答案中显示的方法可行,但服务将在后台运行,直到活动终止,这很昂贵。相反,我建议使用您的 Application 实现。

    1) 创建一个扩展Application的类,然后在Manifest文件的Application标签的name属性中提供它的名字来使用它

    class MusicPlayerApplication: Application() {
        private val TAG = MusicPlayerApplication::class.java.simpleName
    
        override fun onCreate() {
            super.onCreate()
    
            registerActivityLifecycleCallbacks(object: ActivityLifecycleCallbacks {
                override fun onActivityPaused(activity: Activity?) {
    
                }
    
                override fun onActivityResumed(activity: Activity?) {
                }
    
                override fun onActivityStarted(activity: Activity?) {
                }
    
                override fun onActivityDestroyed(activity: Activity?) {
                    Log.d(TAG, "onActivityDestroyed: ")
                    val activityName = activity!!.localClassName
                }
    
                override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
                }
    
                override fun onActivityStopped(activity: Activity?) {
                }
    
                override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
                }
            })
        }
    }
    

    AndroidManifest.xml

    <application
                android:name=".MusicPlayerApplication"
    ....
    
    

    我已经使用 logcat 测试了这种方法,我的 onDestory 没有被调用,但回调中的 onActivityDestroyed 每次我从 RAM 中终止活动时都会被调用,但 this doconActivityDestroyed 会在什么时候被调用onDestory 的活动被调用,但似乎没有发生。但是,我发现这种方法比使用 services 更好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-21
      相关资源
      最近更新 更多