捕获 "Unfortunately 'app' has stopped working" 错误

Catch "Unfortunately 'app' has stopped working" Error

我在 Android 上使用一个非常不稳定的库,偶尔会崩溃。我在我的代码中使用 startActivity() 启动它。

代码的不稳定部分是进行大量视频处理并将结果上传到服务器。我真的不介意 activity 是否崩溃,但我需要向服务器发出崩溃的信号。

崩溃是由内存泄漏引起的(还没来得及解决)。有没有一种方法可以捕获错误并显示更多 friendly/funny 消息?

try {
    context.startActivity(intent);
} catch (ApplicationCrashedException e) {
    server.notifyServerOfCrash();
    toast("I really disliked your face...");
}

编辑:这是错误:

java.lang.OutOfMemoryError
  at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
  at java.nio.MemoryBlock.allocate(MemoryBlock.java:125)
  at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:72)
  at io.cine.android.streaming.FFmpegMuxer.writeSampleData(FFmpegMuxer.java:151)
  at io.cine.android.streaming.AndroidEncoder.drainEncoder(AndroidEncoder.java:128)
  at io.cine.android.streaming.TextureMovieEncoder.handleFrameAvailable(TextureMovieEncoder.java:264)
  at io.cine.android.streaming.TextureMovieEncoder$EncoderHandler.handleMessage(TextureMovieEncoder.java:409)
  at android.os.Handler.dispatchMessage(Handler.java:102)
  at android.os.Looper.loop(Looper.java:136)
  at io.cine.android.streaming.TextureMovieEncoder.run(TextureMovieEncoder.java:219)
  at java.lang.Thread.run(Thread.java:841)

出于某种原因,一旦 BroadcastActivity 内存不足,Activity 就会被杀死并返回到前一个。然后显示 'app' 已停止工作对话框。如果我按确定,它会终止整个应用程序并返回主屏幕。

理想情况下,我会让它返回到之前的 activity 静默通知服务器。 (不杀死应用程序)

Is there a way I can catch the error a display a more friendly/funny message instead?

如果应用程序泄漏太多内存以至于崩溃,您无法轻易捕捉到它。

为什么你不能总是抓住这个

当您启动 运行 内存不足时,您的应用程序代码中任何试图分配超过可用内存的部分都会抛出异常。因此,不只是您的库会抛出异常。

你如何检测到这个

捕获 OutOfMemoryError 并努力告诉 user/server

您的结果会有所不同,但您可以使用 try catch 对包装 Threadrun() 方法并尝试捕获内存不足错误。你仍然会内存不足,你在 catch 代码中做的任何事情都可能因此失败。如果进程频繁分配 内存块,这意味着仍然有一点剩余,它仍然可能有效。

示例:

public void run() {
    try {
        //video process code
    } catch (OutOfMemoryError error) {
        //we are still out of memory so these operations might fail
        tellServerWeFailed();
        triggeruserDialog();
    }
}

onTrimMemory() 覆盖

您也可以尝试在调用 onTrimMemory() 时停止您的视频任务。你的里程可能会有所不同,我从来没有能够让它在不同的 Android 设备上一致地工作。

错误报告框架

一个非常复杂的解决方案是使用第三方错误报告框架,因为它们通常会让您向用户显示自定义崩溃消息。

查看 http://www.acra.ch/ and specifically the documentation on User Messages

开始服务

I do not really mind if the activity crashes, but I need to signal the server that it did.

太棒了!您可能会尝试使用已启动的服务 android 在崩溃后自动重新启动。有关如何告诉您的服务器的详细信息由您决定。您可能会发现您需要保存一些令牌或其他信息,以便您可以告诉您的服务器哪个会话已经结束,这样您就可以,例如,始终将该信息保存在首选项条目中,并在崩溃后读出。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.v(LOG_TAG, "Received start id " + startId + ": " + intent);
    if (intent == null) {
        Log.w(LOG_TAG, "Service was stopped and automatically restarted by the system. ");
        //Tell your server about the crash.
        stopSelf();
    }
    // We want this service to continue running until it is explicitly
    // stopped, so return sticky.
    return START_STICKY;
}

http://developer.android.com/reference/android/app/Service.html#ServiceLifecycle

有关 运行 内存不足的更多信息 Android

To maintain a functional multi-tasking environment, Android sets a hard limit on the heap size for each app. The exact heap size limit varies between devices based on how much RAM the device has available overall. If your app has reached the heap capacity and tries to allocate more memory, it will receive an OutOfMemoryError.

In some cases, you might want to query the system to determine exactly how much heap space you have available on the current device—for example, to determine how much data is safe to keep in a cache. You can query the system for this figure by calling getMemoryClass(). This returns an integer indicating the number of megabytes available for your app's heap. This is discussed further below, under Check how much memory you should use. (source)

一些要点:

  • 您的整个应用共享系统分配的内存堆。
  • 一旦你泄漏了内存,它就会消失,直到应用程序重新启动。
    • 您将无法通过保留 activity.
    • 来隔离一个 activity 中泄漏的内存

如果您正在寻找要捕获的 Exception 类型,只需重复使您的应用程序崩溃所采取的步骤并查看 logcat。您应该会看到类似 "SomeTypeOfException thrown" 的消息。

编辑:否则使用通用 Exception