如何知道android应用程序上次是不是崩溃

Posted

技术标签:

【中文标题】如何知道android应用程序上次是不是崩溃【英文标题】:How to know if android application was crashed last time如何知道android应用程序上次是否崩溃 【发布时间】:2015-03-10 02:01:43 【问题描述】:

我有一个 android 应用程序,我想在这个应用程序启动时知道我的应用程序之前是否崩溃过。此崩溃可能是由应用程序上的操作系统强制崩溃以节省内存或任何其他原因。它可能不会被 UnhandledExceptionHandler 捕获。我到目前为止处理的内容如下所示,它没有缓存那些与本机操作系统相关的和内存强制的案例

UncaughtExceptionHandler handler = new UncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(handler);

编辑:

请不要推荐第 3 方库。

【问题讨论】:

看看this question,听起来你想要这样的东西。 @G_V 我已经调查过了,但它向我展示了外部库以及这些报告也不会捕获与操作系统相关的崩溃,如内存崩溃等 您不能要求您的应用程序检测之前发生的系统崩溃,因为它甚至没有注意到它。它刚刚被操作系统/内核杀死。你问的是不可能的,至少在那个程度上是不可能的。 【参考方案1】:

这将通过SharedPreferences 发生,首先当您在MainActivity 中输入您的应用程序时,创建一个名为crashboolean 变量并将其保存到您的SharedPreferences,值为@987654326 @,那么当遇到崩溃时,只需使用值true 重新保存此变量,这将自动覆盖之前存储的 crash 值。

保存值:

private void savePreferences(String key, String value) 
    SharedPreferences sharedPreferences = PreferenceManager
            .getDefaultSharedPreferences(this);
    Editor editor = sharedPreferences.edit();
    editor.putBoolean("crash", false);
    editor.commit();

加载保存的值:

private void loadSavedPreferences() 
    SharedPreferences sharedPreferences = PreferenceManager
            .getDefaultSharedPreferences(this);
    boolean crash = sharedPreferences.getBoolean("crash", false);
    if(crash)
        // then your app crashed the last time
    else
        // then your app worked perfectly the last time
    

因此,在您的崩溃处理程序类中,只需将值保存为 true:

附言这必须针对来自应用程序或操作系统的所有未处理异常运行。

public class CrashHandler extends Application

    public static Context context;

    public void onCreate()
        super.onCreate();

        CrashHandler.context = getApplicationContext();
        // Setup handler for uncaught exceptions.
        Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
        
          @Override
          public void uncaughtException (Thread thread, Throwable e)
          
            handleUncaughtException (thread, e);
          
        );

    

    public void handleUncaughtException (Thread thread, Throwable e)
    
      e.printStackTrace(); // not all Android versions will print the stack trace automatically

      SharedPreferences sharedPreferences = PreferenceManager
                .getDefaultSharedPreferences(context);
        Editor editor = sharedPreferences.edit();
        editor.putBoolean("crash", true);
        editor.commit();

    


【讨论】:

但我的问题是内存泄漏和其他操作系统生成的崩溃没有在您的上述代码中捕获如何获取它们? 任何应用崩溃都必须被上面的代码捕捉到,如果应用崩溃没有被上面的代码捕捉到,那么请给我关于你的日志的提示。【参考方案2】:

我发现了一个 hack,它对我有用。如果知道用户是否离开应用程序或关闭系统或做了任何此类事情或应用程序本身已关闭,则可以检查其应用程序是否崩溃。如果应用程序本身被关闭,则意味着它已经崩溃,否则它不是(例如用户关闭应用程序或关闭系统)。

在共享首选项的帮助下,可以存储并获取一个变量,该变量将判断应用程序是否崩溃,代码如下所示

public class Activity 
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) 
    boolean appcrashed=false;
    super.onCreate(savedInstanceState);
    boolean didUserLeft=loadSavedPreferences();
    appcrashed=!didUserLeft;
    if(appcrashed)
        Toast.makeText(this, "App Crashed!", Toast.LENGTH_LONG).show();
    else
        Toast.makeText(this, "App OK!", Toast.LENGTH_LONG).show();
    savePreferences(false);

    UnhandledExceptionHandler handler = new UnhandledExceptionHandler();

    Thread.setDefaultUncaughtExceptionHandler(handler);




public boolean loadSavedPreferences() 
    SharedPreferences sharedPreferences = PreferenceManager
            .getDefaultSharedPreferences(this);
    boolean didUserLeft = sharedPreferences.getBoolean("didUserLeft", true);
    return didUserLeft;


public void savePreferences(boolean value) 
    SharedPreferences sharedPreferences = PreferenceManager
            .getDefaultSharedPreferences(this);
    Editor editor = sharedPreferences.edit();
    editor.putBoolean("didUserLeft", value);
    editor.commit();


@Override
public void onResume()
    super.onResume();
    savePreferences(false);


@Override
public void onDestroy()
    savePreferences(true);


@Override
public void onPause() 
    super.onPause();  // Always call the superclass method first
    savePreferences(true);
    


@Override
public void onUserLeaveHint()
    savePreferences(true);

【讨论】:

如果用户清除 ram 它将返回 true,但没有发生崩溃!【参考方案3】:

1) 当 Android 杀死并重新启动您的应用程序时,静态变量被设置为 null(更准确地说,最初设置为 null,稍后很快,设置为它们的初始值;静态初始化程序可能会在变量中看到 null尚未初始化)。因此,如果某个静态变量设置为 null 而 Bundle 中的数据表明用户一直在做某事,则会重新启动进程(我假设您知道 Bundle 在 onCreate(Bundle)).

2) 你可能在持久存储中有一个标志;例如,该标志将在应用程序启动时设置为 true,并在应用程序正常完成之前设置为 false。如果在应用程序启动时该标志为真,则发生崩溃。 (应用正常关闭后崩溃的可能性还是很小的……但是对你来说重要吗?)

3) 您可以将应用的 pid 保存在持久内存中(请参阅myPid())。

【讨论】:

但是当用户从任务栏关闭应用程序或用户关闭操作系统时怎么办? IMO 这两个与杀死进程没有什么不同,尤其是在用户取出电池的情况下。我怀疑在关闭您的应用程序时会调用 onDestroy()。

以上是关于如何知道android应用程序上次是不是崩溃的主要内容,如果未能解决你的问题,请参考以下文章

如何知道一个进程是不是已启动但在 Linux 中崩溃

在android中检测应用程序崩溃

如何使用报告按钮获取崩溃对话框

如何找到切换按钮崩溃的原因?

Android - 恢复上次查看的活动

如何对运行 Android 11 (SDK 30) 的应用程序崩溃进行故障排除