赶上"不幸的是' app'已停止工作"错误

时间:2015-06-30 21:40:41

标签: android android-activity error-handling ffmpeg android-lifecycle

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

代码的不稳定部分正在进行大量视频处理并将结果上传到服务器。我不介意活动是否崩溃,但我需要向服务器发出信号,表明它已经崩溃了。

崩溃来自内存泄漏(没时间解决它)。有没有办法可以捕捉错误显示更友好/有趣的消息呢?

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内存不足,活动就会被杀死并返回上一个活动。然后它会显示“应用程序”。已停止工作Dialog。如果我按OK,它将终止整个应用程序并返回主屏幕。

理想情况下,我会让它回到上一个以静默方式通知服务器的活动。 (不杀死申请)

2 个答案:

答案 0 :(得分:1)

  

有没有办法可以捕捉错误显示更友好/有趣的消息呢?

如果应用程序泄漏了太多内存而导致崩溃,那么就无法轻易抓住它。

为什么无法总是抓住这个

当您开始耗尽内存时,会从应用程序代码的任何部分抛出异常,这些部分会尝试分配比可用内存更多的内存。因此,只是你的库会抛出异常。

如何检测到

捕获OutOfMemoryError并努力告诉用户/服务器

您的结果会有所不同,但您可以使用Thread对包裹run()的{​​{1}}方法并尝试捕获内存不足错误。你仍然会内存不足,你在catch代码中做的任何事情都可能因为它而失败。如果进程经常分配块内存,这意味着仍有一点点剩余,那么它仍然有效。

示例:

try catch

onTrimMemory()覆盖

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

错误报告框架

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

查看http://www.acra.ch/,特别是User Messages

上的文档

开始服务

  

我真的不介意活动是否崩溃,但我需要向服务器发出信号。

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

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

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

有关Android

内存不足的更多信息
  

为了维护功能性多任务环境,Android为每个应用程序设置了堆大小的硬限制。根据设备总体可用的RAM量,确切的堆大小限制因设备而异。如果您的应用程序已达到堆容量并尝试分配更多内存,则会收到OutOfMemoryError。

     

在某些情况下,您可能希望查询系统以准确确定当前设备上可用的堆空间大小 - 例如,确定可以安全地保留在缓存中的数据量。您可以通过调用getMemoryClass()来查询系统中的这个数字。这将返回一个整数,指示应用程序堆可用的兆字节数。这将在下面进一步讨论,检查您应该使用多少内存。 (source)

一些关键点:

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

答案 1 :(得分:0)

如果您正在寻找要捕获的Exception类型,请重复您为使应用程序崩溃所采取的步骤,并查看logcat。您应该会看到一条消息,例如" SomeTypeOfException抛出"赶上那个。

编辑:否则使用通用Exception