Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/199.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在应用程序关闭且bg中正在运行服务后,如何强制应用程序onCreate?_Android_Android Service_Android Lifecycle_Android Service Binding_Android Application Class - Fatal编程技术网

Android 在应用程序关闭且bg中正在运行服务后,如何强制应用程序onCreate?

Android 在应用程序关闭且bg中正在运行服务后,如何强制应用程序onCreate?,android,android-service,android-lifecycle,android-service-binding,android-application-class,Android,Android Service,Android Lifecycle,Android Service Binding,Android Application Class,基本上我有一个运行前台服务的应用程序。 启动应用程序时,我需要在应用程序的onCreate方法中执行特定于会话的初始化 当我关闭应用程序时,服务将继续运行(期望的行为),但是,当我从启动器/从我的通知重新打开应用程序时,不会再次调用应用程序onCreate 我的问题是: 即使有服务正在运行,如何强制再次调用应用程序onCreate?(服务可能正在保留对应用程序对象的引用,对吗?) 是否有一种方法可以在应用程序类中获得应用程序已重新启动但来自服务的指示 你还能想到什么其他的解决方案 Android

基本上我有一个运行前台服务的应用程序。 启动应用程序时,我需要在应用程序的
onCreate
方法中执行特定于会话的初始化

当我关闭应用程序时,服务将继续运行(期望的行为),但是,当我从启动器/从我的通知重新打开应用程序时,不会再次调用应用程序
onCreate

我的问题是:

  • 即使有服务正在运行,如何强制再次调用应用程序
    onCreate
    ?(服务可能正在保留对应用程序对象的引用,对吗?)
  • 是否有一种方法可以在应用程序类中获得应用程序已重新启动但来自服务的指示
  • 你还能想到什么其他的解决方案
  • AndroidManifest.xml
    中的MyService:

    <service android:name=".MyService"
        android:exported="false"/>
    

    在创建对象的过程中触发onCreate事件。之后就开始了。 如果应用程序已关闭,则该对象在内存中仍处于活动状态,如果设备需要更多可用资源,该对象将被销毁。 因此,如果重新打开应用程序,则只会触发onStart事件。 尝试在onStart中移动初始化,或在onStart中进行检查或类似操作

    活动的生命周期
    应用程序对象是单例对象。当创建承载应用程序的操作系统进程时,它将被实例化(并调用
    onCreate()
    )。如果您的应用程序正在托管前台
    服务
    ,则该操作系统进程将继续存在,因此不会调用
    Application.onCreate()

    我不太清楚为什么需要调用它,但是你可以让你的
    服务
    在不同于应用程序的其他组件(
    活动
    广播接收器
    提供者
    )的操作系统进程中运行。在这种情况下,托管前台
    服务的操作系统进程将不会被重新创建,但托管您的活动的操作系统进程将被重新创建(如果它被Android关闭,如果没有活动组件运行,通常会发生这种情况)。由于
    应用程序
    对象存在于每个操作系统进程中,因此当重新创建承载活动的操作系统进程时,Android将实例化一个新的
    应用程序
    对象,并在该对象上调用
    onCreate()

    要让您的
    服务
    在不同的操作系统进程中运行,只需将其添加到清单中的
    标记:

    android:process=":remote"
    
    注意:您可以使用任何您想要的名称而不是“remote”,只要确保它以冒号(“:”)开头即可


    警告:您需要知道您的应用程序有2个操作系统进程,并相应地计划。这两个进程中运行的代码彼此无法看到,因此这可能会导致应用程序中出现其他问题。您在组件之间共享的任何数据(例如,
    服务
    活动
    )都需要放入数据库或共享首选项或其他机制中,以便在操作系统进程之间共享。

    我建议您创建一个包含初始代码的实用程序函数。 使用标志查看是否需要运行操作,如果设置了此标志,则不执行任何操作

    从基本活动(而不是从应用程序)调用此函数,因为您遇到了确切的问题。它还允许在初始化期间向用户提供反馈

    一旦用户退出,清除该标志


    因此,基本上,将代码移动到一个可以一致调用的位置。

    您可以在
    应用程序中创建
    ProcessLifeCycleOwner
    并侦听生命周期事件。您可能还需要为类设置一个标志,并从方法中获取该值,以检查用户在按下home按钮或使用通知启动应用程序后是否返回

    class MyApp: Application() {
    
        override fun onCreate() {
            super.onCreate()
    
            ProcessLifecycleOwner
                .get()
                .lifecycle
                .addObserver(ApplicationObserver())
        }
    
        inner class ApplicationObserver : LifecycleObserver {
    
            @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
            fun onStop() {
            }
    
            @OnLifecycleEvent(Lifecycle.Event.ON_START)
            fun onStart() {
    
            }
    
            @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
            fun onCreate() {
    
            }
    
    
            @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
            fun onDestroy() {
    
            }
        }
    }
    

    找到查找已启动的应用程序(至少是已启动的第一个活动)的方法,然后在
    onCreate()
    上根据需要进行初始化。我和你面临着同样的情况,应用程序必须在启动和离开时做一些事情。我创建了一个界面来监听应用程序是否进入前台和后台模式(没有活动运行):

    然后我创建一个类来检测应用程序是否进入背景和前景

    class AppLifeCycleTracker(private val iApplicationLifeCycle: IApplicationLifeCycle? = null) : Application.ActivityLifecycleCallbacks {
    private var aliveActivityCount = 0 // created on destroyed
    private var activeActivityCount = 0 // started on stopped
    private var liveActivityCount = 0 // resumed on paused
    
    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
        aliveActivityCount++
        if (aliveActivityCount == 1) {
            iApplicationLifeCycle?.onFirstCreated()
        }
    }
    
    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
    
    override fun onActivityStarted(activity: Activity) {
        activeActivityCount++
    }
    
    override fun onActivityResumed(activity: Activity) {
        liveActivityCount++
        if (liveActivityCount == 1 && activeActivityCount == 1) {
            iApplicationLifeCycle?.onEnterForeground()
        }
    }
    
    override fun onActivityPaused(activity: Activity) {
        liveActivityCount--
    }
    
    override fun onActivityStopped(activity: Activity) {
        activeActivityCount--
        if (liveActivityCount == 0 && activeActivityCount == 0) {
            iApplicationLifeCycle?.onEnterBackground()
        }
    }
    
    override fun onActivityDestroyed(activity: Activity) {
        aliveActivityCount--
        if (aliveActivityCount == 0) {
            iApplicationLifeCycle?.onLastDestroyed()
        }
    }
    
    }

    根据我的申请

    class MyApplication: IApplicationLifeCycle{
    
        onCreate() {
            super.onCreate() 
            registerActivityLifecycleCallbacks(AppLifeCycleTracker(this))
        }
    
        override fun onEnterForeground() {
            Log.i("AppVisibility", "onEnterForeground")
            // do action here
        }
    
        ...
        ...
        ...
    }
    

    在Overrided method上,
    OneInterForeground
    只需执行您想要的操作,在这种情况下,您需要进行一些初始化

    我认为您应该在您的服务执行其预期任务后使用
    stopForground
    。即使我使用它,也不会有任何帮助,因为这是一个很长的操作。一旦我再次启动我的应用程序,应用程序oncreate将不会被调用,因为它仍然没有完成其操作。是否可以使用线程而不是服务?不…这是不可能的。
    当我关闭应用程序时
    你的意思是你只是最小化应用程序还是从最近的应用程序列表中清除应用程序?我说的是应用程序,不是活动生命周期。应用程序生命周期没有开始在清单中尝试这一点这对我的问题有什么帮助?我已经尝试过这种方法,但是应用程序对象没有被重新创建。(我再试一试)只有在Android关闭操作系统进程的情况下,才会重新创建
    应用程序。但是,即使你关闭了所有的活动,也不能保证会发生这种情况。您可能需要重新考虑您的体系结构,因为您不能依赖这种行为。你到底想完成什么?您可能需要以不同的方式处理此问题无法保证它会发生您对此的看法是正确的,但它通常会发生,以防它不在流程中。我的用例实际上是在每次创建应用程序时从头开始初始化SDK,这在使用服务时不会发生,因此对于我的最终用户来说,这是一种奇怪的行为。。。我确实找到了其他的解决办法——只是想知道我是否还有别的办法
    
    class AppLifeCycleTracker(private val iApplicationLifeCycle: IApplicationLifeCycle? = null) : Application.ActivityLifecycleCallbacks {
    private var aliveActivityCount = 0 // created on destroyed
    private var activeActivityCount = 0 // started on stopped
    private var liveActivityCount = 0 // resumed on paused
    
    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
        aliveActivityCount++
        if (aliveActivityCount == 1) {
            iApplicationLifeCycle?.onFirstCreated()
        }
    }
    
    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
    
    override fun onActivityStarted(activity: Activity) {
        activeActivityCount++
    }
    
    override fun onActivityResumed(activity: Activity) {
        liveActivityCount++
        if (liveActivityCount == 1 && activeActivityCount == 1) {
            iApplicationLifeCycle?.onEnterForeground()
        }
    }
    
    override fun onActivityPaused(activity: Activity) {
        liveActivityCount--
    }
    
    override fun onActivityStopped(activity: Activity) {
        activeActivityCount--
        if (liveActivityCount == 0 && activeActivityCount == 0) {
            iApplicationLifeCycle?.onEnterBackground()
        }
    }
    
    override fun onActivityDestroyed(activity: Activity) {
        aliveActivityCount--
        if (aliveActivityCount == 0) {
            iApplicationLifeCycle?.onLastDestroyed()
        }
    }
    
    class MyApplication: IApplicationLifeCycle{
    
        onCreate() {
            super.onCreate() 
            registerActivityLifecycleCallbacks(AppLifeCycleTracker(this))
        }
    
        override fun onEnterForeground() {
            Log.i("AppVisibility", "onEnterForeground")
            // do action here
        }
    
        ...
        ...
        ...
    }