Android 是否有可能知道用户通过设置强制退出后应用程序是否启动?

Android 是否有可能知道用户通过设置强制退出后应用程序是否启动?,android,android-lifecycle,Android,Android Lifecycle,我想知道,可能是在我活动的onCreate()中,应用程序之前是否按照正常的home/back按钮关闭,或者用户是否实际进入Android设置并选择强制关闭 有可能区分这两种情况吗 编辑: 我想我可能没有很好地解释我的意思。我已经阅读了“活动生命周期”文档,对此我非常理解 基本上,我只想知道活动是什么时候创建的,用户是否已经进入Android设置并点击强制停止。如果应用程序被强制停止,我想采取行动(特别是在启动时显示启动屏幕) 下面的很多答案都说,我可以在onStop()或onDestroy()

我想知道,可能是在我活动的onCreate()中,应用程序之前是否按照正常的home/back按钮关闭,或者用户是否实际进入Android设置并选择强制关闭

有可能区分这两种情况吗

编辑:

我想我可能没有很好地解释我的意思。我已经阅读了“活动生命周期”文档,对此我非常理解

基本上,我只想知道活动是什么时候创建的,用户是否已经进入Android设置并点击强制停止。如果应用程序被强制停止,我想采取行动(特别是在启动时显示启动屏幕)

下面的很多答案都说,我可以在onStop()或onDestroy()中设置一个标志,并且如果用户点击force stop,这些方法将不会被调用。问题是,由于以下顺序,这些方法在到达该点之前就已经被调用了:

  • 应用程序处于活动状态,正在使用中
  • 用户点击后退按钮(调用onStop(),onDestroy()),或主页按钮(调用onStop()),或最近的应用程序按钮(调用onStop())
  • 用户进入android设置,点击强制停止
  • 在这种情况下,我会在onStop()上将该标志放入共享首选项中,但随后用户点击force stop,该标志在onCreate()中仍然处于活动状态


    我不想显示启动屏幕,除非用户在设置中点击了强制停止。我知道这不是应该做的。。。但是这个决定不是我做的。

    如果用户用“强制关闭”关闭了您的应用程序,“onStop”方法不会执行。您可以在该方法中放置一个标志(如保存在文件中、用户首选项、sql等)。下次应用程序启动时,请检查该标志

    覆盖主页活动中按下的
    onbackbutton
    (在正常情况下,使用后退按钮关闭应用程序主活动)

    在此函数中设置一个变量(例如,lastforceClose为false)SharedReferences,然后调用onbackbuttonpressed()或finish()的超级方法来结束活动

    下次启动活动时,您可以在SharedReferences中检查变量,查看lastforceClose变量是否设置为false(现在您自己将其更改为true)


    当用户通过android设置
    删除了数据时,您可能还想在这里处理这种情况。。(例如,共享首选项xml文件中不存在密钥等)

    我不是100%确定,但这应该会起作用。
    1) 将状态(正常关机)保存在某些持久性存储上的活动onDestroy中。(SharedReferences或SQLite)

    2) 在状态的onCreate检查中,如果是正常关机,则应用程序正常关闭,否则为强制关闭。重置状态。

    我不确定是否有更简单的方法,但您可以创建一个SharedReferences对象,该对象在活动的onStop函数中使用一个标志进行更新。并检查onCreate中的标志。如果用户强制关闭应用程序,我认为不会调用onStop或onDestroy

    首先,听起来您可能会混淆恢复和创建。一定要通读应用程序的基础知识,特别是关于。这个状态图很有用

    当用户“退出”应用程序时,它不一定会被销毁。事实上,它可能不会被销毁,除非开发人员在显式销毁活动的
    onPause()
    中放入一些钩子

    Android应用程序生命周期中最重要的一个概念是:

    安卓操作系统绝对不能保证你的应用程序能存活多久,除非你保证不管你是否愿意,它随时都可能死亡。


    您应该始终编写相应的应用程序,并且填充生命周期启动和结束挂钩的每一个是一个好的实践。当用户从应用程序中按硬件按钮退出时,应用程序不一定会被销毁,但当通过强制退出关闭应用程序时,应用程序将被完全销毁。与其试图骗你弄清楚应用程序是如何关闭的,“正确”的处理方法是根据活动状态设置
    onPause()
    onStop()
    、和
    onDestroy()
    方法进行适当的清理,并且可能有某种偏好对象或状态变量,只有在调用
    ondestory()
    时才会被翻转,因为从技术上讲,操作系统仍然可以“强制退出”即使用户没有通过任务管理器执行此操作,应用程序也会自动启动。

    您可以尝试保留所有应用程序生命周期事件的记录,然后检查您的各种
    onCreate()s
    是否记录了上一个事件是否正常。如果没有,你可以合理地推断出发生了什么事。我猜用户调用的任何强制关闭都会导致系统向应用程序发送一个
    kill(2)
    ,在这种情况下,您不会收到任何指示。也许会有帮助

    你也可以考虑是否可以以不同的方式实现你所追求的目标。如果你的应用程序是完全无状态的,那么任何类型的关机都不会有问题。如果你的应用程序有状态,那么理论上你的所有数据/应用程序事务都可以实现一致性,因此你可以避免由于崩溃/强制关闭而导致的不一致


    这有帮助吗?还是你在追求其他东西?

    从服务而不是活动中写入状态标志怎么样?活动生命周期仍将完成,但服务生命周期不应完成

    它与您的需求不完全相同,但可能已经足够接近了。如果显示的活动不符合此要求,则需要停止服务(稍后重新启动)。或者让服务编写一个
    package com.mehuljoisar.forcestopdemo;
    
    public class CONSTANTS {
    
    //the changes made to value of below variable will be cleared on force stop,so whenever force stop occurs,the value of variable will be "isForceStopped=true" again.
        public static boolean isForceStopped = true;
    }
    
    package com.mehuljoisar.forcestopdemo;
    
    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.Menu;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
    
        private Context mContext;
        private Intent i;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            initialize();
    
    
            if(CONSTANTS.isForceStopped)
            {
            //this block of code will be executed in 2 scenario,
            //1: when application is started for very first time
            //2: when application is started after force stopping
                Toast.makeText(mContext, "Display Splash-screen and move to next screen", Toast.LENGTH_SHORT).show();
            //don't forget this part,it's important to make change so that next time splash screen can be avoided
                 CONSTANTS.isForceStopped=false;
    
            //and then launch next screen
                launchSecondScreen();
            }
            else
            {
            //directly launch next screen
                launchSecondScreen();
            }
        }
    
        private void launchSecondScreen() {
            i.setClass(mContext, SecondActivity.class);
            startActivity(i);
            finish();
        }
    
        private void initialize() {
            mContext = this;
            i = new Intent();
        }
    
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.activity_main, menu);
            return true;
        }
    
    }
    
    package com.mehuljoisar.forcestopdemo;
    
    import android.app.Activity;
    import android.os.Bundle;
    
    public class SecondActivity extends Activity{
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_second);
        }
    
    }
    
        <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.mehuljoisar.forcestopdemo"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="16" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.mehuljoisar.forcestopdemo.MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity
                android:name="com.mehuljoisar.forcestopdemo.SecondActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
    
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>