Android应用程序在运行时突然崩溃?

30

我的应用程序是做什么的? 我正在开发的应用程序是一种典型的客户端服务器应用程序,使用 Wifi 与 Windows 服务器通信。该应用程序具有多个活动和重的内存和 CPU 要求,例如 speex 编码/解码的本机调用。

我的问题是什么? 问题是应用程序在正常工作时突然重新启动。有时,在正常工作时突然看到(在 LogCat 中)调用了 Application 类的构造函数(该类扩展了 API 的 Application 类)。这会导致我的应用程序崩溃,因为所有全局数据都存储在应用程序类中。

我已经做了什么? 我想到的第一件事是 Android 可能感觉到低内存,因此终止了我的应用程序,并自动重新启动了它。因此,我实现了应用程序类的 onLowMemory() 方法。但令我惊讶的是,它从未被调用过。

主要问题是什么? 主要问题是 LogCat 上没有任何内容打印。看起来即使 Android 自身也不知道为什么重新启动了我的已运行应用程序?

可能的原因是什么导致了突然重启?我该如何避免这种情况?

我正在 Galaxy Y 上工作,API 版本为 2.3.6。我的 AndroidManifest.xml 如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="some.package.MyApp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:maxSdkVersion="15"
        android:minSdkVersion="10"
        android:targetSdkVersion="10" />

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_VIDEO" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <application
        android:name="some.package.MyApp"
        android:icon="@drawable/display_image"
        android:label="@string/app_name" >
        <activity
            android:name="some.package.LoginActivity"
            android:configChanges="keyboardHidden|orientation"
            android:label="@string/app_name"
            android:screenOrientation="user" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="some.package.BuddyListActivity"
            android:configChanges="keyboardHidden|orientation"
            android:label="@string/app_name"
            android:screenOrientation="user"
            android:theme="@android:style/Theme.Black.NoTitleBar" >

            <!--
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            -->
        </activity>
        <activity
            android:name="some.package.SessionWindowActivity"
            android:configChanges="keyboardHidden|orientation"
            android:label="@string/app_name"
            android:screenOrientation="user"
            android:theme="@android:style/Theme.Black.NoTitleBar" >

            <!--
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            -->
        </activity>
    </application>

</manifest>

编辑 在使用CheckJNI后,我刚刚在LogCat中看到以下输出:

06-26 17:27:30.023: I/remove(24544): Sending Signal : 13 **//App Working fine here**
06-26 17:27:32.148: D/dalvikvm(24544): GC_CONCURRENT freed 446K, 49% free 3384K/6599K, external 1057K/1076K, paused 3ms+4ms
06-26 17:27:39.531: W/dalvikvm(24544): **HeapWorker may be wedged: 7374ms spent** inside LsomePackageName/modules/AudioPlayer;.finalize()V
06-26 17:27:40.023: I/remove(24544): Sending Signal : 13
06-26 17:27:40.218: D/dalvikvm(24544): GC_CONCURRENT freed 479K, 49% free 3383K/6599K, external 1057K/1076K, paused 9ms+5ms 
06-26 17:27:42.343: E/RoobrooApp(24670): Application Instance created **//Restarted** 
06-26 17:27:42.351: I/ApplicationPackageManager(24670): cscCountry is not German : INS
更新 在进一步实验中,我有意为双精度数组分配了非常大的存储空间。但是出乎意料的是,既没有调用 onLowMemory() 也没有重启应用程序,而是出现了 outOfMemoryException。如果从未调用 onLowMemory(),那为什么会存在呢?

还有一个问题是,在重启操作系统后,它已经开始运行 BuddyListActivity 而不是 LoginActivity... 真的需要帮助...

更新2 我刚刚看到以下错误日志,我真的不知道这是什么意思...

06-29 12:07:28.398: W/dalvikvm(19308): ReferenceTable overflow (max=1024)
06-29 12:07:28.398: W/dalvikvm(19308): Last 10 entries in JNI pinned array reference table:
06-29 12:07:28.398: W/dalvikvm(19308):  1014: 0x405b0280 cls=[B (340 bytes)
06-29 12:07:28.398: W/dalvikvm(19308):  1015: 0x405b03d8 cls=[S (660 bytes)
06-29 12:07:28.398: W/dalvikvm(19308):  1016: 0x405d8208 cls=[B (340 bytes)
06-29 12:07:28.398: W/dalvikvm(19308):  1017: 0x405d8360 cls=[S (660 bytes)
06-29 12:07:28.398: W/dalvikvm(19308):  1018: 0x405f8b08 cls=[B (340 bytes)
06-29 12:07:28.398: W/dalvikvm(19308):  1019: 0x405f8c60 cls=[S (660 bytes)
06-29 12:07:28.398: W/dalvikvm(19308):  1020: 0x405f8ef8 cls=[B (340 bytes)
06-29 12:07:28.398: W/dalvikvm(19308):  1021: 0x405ff698 cls=[S (660 bytes)
06-29 12:07:28.398: W/dalvikvm(19308):  1022: 0x405f9050 cls=[B (340 bytes)
06-29 12:07:28.398: W/dalvikvm(19308):  1023: 0x405ff930 cls=[S (660 bytes)
06-29 12:07:28.398: W/dalvikvm(19308): JNI pinned array reference table summary (1024 entries):
06-29 12:07:28.398: W/dalvikvm(19308):     1 of [B 20B
06-29 12:07:28.398: W/dalvikvm(19308):   508 of [B 340B (508 unique)
06-29 12:07:28.398: W/dalvikvm(19308):     3 of [B 348B (3 unique)
06-29 12:07:28.406: W/dalvikvm(19308):   511 of [S 660B (511 unique)
06-29 12:07:28.406: W/dalvikvm(19308):     1 of [S 668B
06-29 12:07:28.406: W/dalvikvm(19308): Memory held directly by tracked refs is 511712 bytes
06-29 12:07:28.406: E/dalvikvm(19308): Failed adding to JNI pinned array ref table (1024 entries)
06-29 12:07:28.406: I/dalvikvm(19308): "Thread-14" prio=5 tid=12 RUNNABLE
06-29 12:07:28.406: I/dalvikvm(19308):   | group="main" sCount=0 dsCount=0 obj=0x4050e548 self=0x2240b8
06-29 12:07:28.406: I/dalvikvm(19308):   | sysTid=19953 nice=-19 sched=0/0 cgrp=[fopen-error:2] handle=1905240
06-29 12:07:28.406: I/dalvikvm(19308):   | schedstat=( 207153329 82244881 1015 )
06-29 12:07:28.406: I/dalvikvm(19308):   at some.package.MyApp.speex.SpeexEncoder.encode(Native Method)
06-29 12:07:28.406: I/dalvikvm(19308):   at some.package.MyApp.speex.SpeexEncoder.encodeFrame(SpeexEncoder.java:51)
06-29 12:07:28.406: I/dalvikvm(19308):   at some.package.MyApp.models.Session.capturedAudioReceived(Session.java:656)
06-29 12:07:28.406: I/dalvikvm(19308):   at some.package.MyApp.modules.AudioCapturer.run(AudioCapturer.java:118)
06-29 12:07:28.406: I/dalvikvm(19308):   at java.lang.Thread.run(Thread.java:1019)
06-29 12:07:28.406: E/dalvikvm(19308): VM aborting
06-29 12:07:29.726: W/AudioTrack(19308): obtainBuffer() track 0x1d3520 disabled, restarting
06-29 12:07:30.351: W/dalvikvm(19308): threadid=4: spin on suspend #1 threadid=1 (pcf=0)
06-29 12:07:30.898: W/AudioTrack(19308): obtainBuffer() track 0x1d3520 disabled, restarting
06-29 12:07:31.101: W/dalvikvm(19308): threadid=4: spin on suspend #2 threadid=1 (pcf=0)
06-29 12:07:31.101: I/dalvikvm(19308): "Signal Catcher" daemon prio=5 tid=4 RUNNABLE
06-29 12:07:31.101: I/dalvikvm(19308):   | group="system" sCount=0 dsCount=0 obj=0x40510490 self=0x159898
06-29 12:07:31.101: I/dalvikvm(19308):   | sysTid=19312 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=1575600
06-29 12:07:31.101: I/dalvikvm(19308):   | schedstat=( 1556395 4913328 26 )
06-29 12:07:31.101: I/dalvikvm(19308):   at dalvik.system.NativeStart.run(Native Method)
06-29 12:07:31.101: I/dalvikvm(19308): "main" prio=5 tid=1 RUNNABLE
06-29 12:07:31.101: I/dalvikvm(19308):   | group="main" sCount=1 dsCount=0 obj=0x40022198 self=0xcec8
06-29 12:07:31.101: I/dalvikvm(19308):   | sysTid=19308 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=-1345006496
06-29 12:07:31.101: I/dalvikvm(19308):   | schedstat=( 5364166234 3306213349 13647 )
06-29 12:07:31.101: I/dalvikvm(19308):   at android.media.AudioTrack.native_write_short(Native Method)
06-29 12:07:31.101: I/dalvikvm(19308):   at android.media.AudioTrack.write(AudioTrack.java:943)
06-29 12:07:31.101: I/dalvikvm(19308):   at some.package.MyApp.modules.AudioPlayer.onPeriodicNotification(AudioPlayer.java:163)
06-29 12:07:31.101: I/dalvikvm(19308):   at android.media.AudioTrack$NativeEventHandlerDelegate$1.handleMessage(AudioTrack.java:1084)
06-29 12:07:31.101: I/dalvikvm(19308):   at android.os.Handler.dispatchMessage(Handler.java:99)
06-29 12:07:31.101: I/dalvikvm(19308):   at android.os.Looper.loop(Looper.java:130)
06-29 12:07:31.101: I/dalvikvm(19308):   at android.app.ActivityThread.main(ActivityThread.java:3687)
06-29 12:07:31.101: I/dalvikvm(19308):   at java.lang.reflect.Method.invokeNative(Native Method)
06-29 12:07:31.101: I/dalvikvm(19308):   at java.lang.reflect.Method.invoke(Method.java:507)
06-29 12:07:31.101: I/dalvikvm(19308):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
06-29 12:07:31.101: I/dalvikvm(19308):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
06-29 12:07:31.101: I/dalvikvm(19308):   at dalvik.system.NativeStart.main(Native Method)
06-29 12:07:31.851: W/dalvikvm(19308): threadid=4: spin on suspend #3 threadid=1 (pcf=0)
06-29 12:07:31.851: I/dalvikvm(19308): "Signal Catcher" daemon prio=5 tid=4 RUNNABLE
06-29 12:07:31.851: I/dalvikvm(19308):   | group="system" sCount=0 dsCount=0 obj=0x40510490 self=0x159898
06-29 12:07:31.851: I/dalvikvm(19308):   | sysTid=19312 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=1575600
06-29 12:07:31.851: I/dalvikvm(19308):   | schedstat=( 2868652 6927485 37 )
06-29 12:07:31.851: I/dalvikvm(19308):   at dalvik.system.NativeStart.run(Native Method)
06-29 12:07:31.851: I/dalvikvm(19308): "main" prio=5 tid=1 RUNNABLE
06-29 12:07:31.851: I/dalvikvm(19308):   | group="main" sCount=1 dsCount=0 obj=0x40022198 self=0xcec8
06-29 12:07:31.851: I/dalvikvm(19308):   | sysTid=19308 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=-1345006496
06-29 12:07:31.851: I/dalvikvm(19308):   | schedstat=( 5364166234 3306213349 13647 )
06-29 12:07:32.000: I/dalvikvm(19308):   at android.media.AudioTrack.native_write_short(Native Method)
06-29 12:07:32.015: I/dalvikvm(19308):   at android.media.AudioTrack.write(AudioTrack.java:943)
06-29 12:07:32.031: I/dalvikvm(19308):   at some.package.MyApp.modules.AudioPlayer.onPeriodicNotification(AudioPlayer.java:163)
06-29 12:07:32.039: I/dalvikvm(19308):   at android.media.AudioTrack$NativeEventHandlerDelegate$1.handleMessage(AudioTrack.java:1084)
06-29 12:07:32.054: I/dalvikvm(19308):   at android.os.Handler.dispatchMessage(Handler.java:99)
06-29 12:07:32.054: I/dalvikvm(19308):   at android.os.Looper.loop(Looper.java:130)
06-29 12:07:32.062: W/AudioTrack(19308): obtainBuffer() track 0x1d3520 disabled, restarting
06-29 12:07:32.070: I/dalvikvm(19308):   at android.app.ActivityThread.main(ActivityThread.java:3687)
06-29 12:07:32.093: I/dalvikvm(19308):   at java.lang.reflect.Method.invokeNative(Native Method)
06-29 12:07:32.101: I/dalvikvm(19308):   at java.lang.reflect.Method.invoke(Method.java:507)
06-29 12:07:32.109: I/dalvikvm(19308):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
06-29 12:07:32.125: I/dalvikvm(19308):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
06-29 12:07:32.132: I/dalvikvm(19308):   at dalvik.system.NativeStart.main(Native Method)
06-29 12:07:32.890: W/dalvikvm(19308): threadid=4: spin on suspend #4 threadid=1 (pcf=0)
06-29 12:07:32.890: I/dalvikvm(19308): "Signal Catcher" daemon prio=5 tid=4 RUNNABLE
06-29 12:07:32.890: I/dalvikvm(19308):   | group="system" sCount=0 dsCount=0 obj=0x40510490 self=0x159898
06-29 12:07:32.890: I/dalvikvm(19308):   | sysTid=19312 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=1575600
06-29 12:07:32.890: I/dalvikvm(19308):   | schedstat=( 5340582 316192616 59 )
06-29 12:07:32.898: I/dalvikvm(19308):   at dalvik.system.NativeStart.run(Native Method)
06-29 12:07:32.898: I/dalvikvm(19308): "main" prio=5 tid=1 RUNNABLE
06-29 12:07:32.898: I/dalvikvm(19308):   | group="main" sCount=1 dsCount=0 obj=0x40022198 self=0xcec8
06-29 12:07:32.898: I/dalvikvm(19308):   | sysTid=19308 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=-1345006496
06-29 12:07:32.898: I/dalvikvm(19308):   | schedstat=( 5364166234 3306213349 13647 )
06-29 12:07:32.929: I/dalvikvm(19308):   at android.media.AudioTrack.native_write_short(Native Method)
06-29 12:07:32.945: I/dalvikvm(19308):   at android.media.AudioTrack.write(AudioTrack.java:943)
06-29 12:07:32.953: I/dalvikvm(19308):   at some.package.MyApp.modules.AudioPlayer.onPeriodicNotification(AudioPlayer.java:163)
解决方案 目前测试改变的代码,一切看起来都很顺利。问题出在JNI里面(我猜)。@n.Collins的声明"事实上JVM未报告任何错误,这表明问题由你的本地代码引起。"是指向解决方案的最准确的指针之一。我非常感谢所有回答过我的人,他们对我有所帮助。在尝试解决此问题时,我还删除了一组其他错误,这都要归功于社区。

1
我知道 onLowMemory 没有被调用,但是你是否尝试监控内存使用情况以查找内存泄漏呢?此外,你确定 logcat 中没有任何输出吗?我问这个问题是因为过滤应用程序标签可能会阻止看到所有适用的崩溃消息。确保在崩溃期间查看未经过滤的 logcat 视图。 - ian.shaun.thomas
3
根据文档,onLowMemory()不一定会被调用。我观察到,在本地代码(也可能是Java代码)中的OutOfMemoryErrors可能会导致应用程序崩溃,而没有任何消息或日志记录。 - Rafael T
1
看起来问题出在jni上。您可能需要考虑在jni中添加更多的调试符号。https://groups.google.com/forum/?fromgroups#!topic/android-developers/y8lrC_t56cQ。 - Binoy Babu
1
关于您上一个问题,关于不从LAUNCHER Activity开始的问题,您可以在这里查看我的问题。我曾经遇到过类似的问题https://dev59.com/Tmgu5IYBdhLWcg3wj3v5 - Ovidiu Latcu
1
我怀疑问题出在Android操作系统上,而不是项目本身。 - MKJParekh
显示剩余10条评论
5个回答

19

很难根据不完整的源代码准确地判断发生了什么,但也许Romain Guy在Google Groups上的回答here可以帮助。

onLowMemory()在整个系统即将耗尽内存时被调用,而不是在您的进程即将耗尽内存时。每个应用程序都限制在固定的RAM数量(例如,在Nexus One上为24 MB)。如果您使用了这24 MB,但系统仍有更多的RAM可用,您将收到一个OutOfMemoryError而不是onLowMemory()

对于<Honeycomb上的应用程序,24mb的限制基本上是固定的。如果您的目标API为11或更高版本,则可以通过声明为应用程序分配大堆来请求更多内存。虽然文档中没有提到,但在Manifest.xml中的application标记中添加android:largeHeap="true"将实现此功能(虽然不能保证)。

注意:在修改后的固件(定制ROM)中,该值可能更低或更高。我相信三星Galaxy Nexus默认情况下是48mb,但通常情况下保持在24mb以内是一个安全的假设。此外,索尼爱立信还有一篇great post,解释了Gingerbread和Ice Cream Sandwich之间的技术差异(RAM是一个深入探讨的主题)。祝你好运,希望这至少能帮助你找到问题所在。

我刚刚阅读了几篇博客并观看了Google IO 2011关于Android内存问题的视频会议。学习并解决了一些泄漏问题,但问题仍然存在... - Amit
@anDroider,没有你的源代码很难确定问题所在,但所有迹象都指向某种性能问题。如果你在运行API 11或更高版本的高端设备上尝试过,并且使用了largeHeap="true",结果是否相同?或者在你的本地代码中添加一些日志调用,看看它们在哪里停止。也许你有一些无限递归、循环或内存泄漏问题是你不知道的。 - Tom
2
在Nexus One上它是16MB,我使用以下代码: long heap = Debug.getNativeHeapAllocatedSize() / 1024; 对于那些允许用户不断加载图片的应用程序,在堆接近16MB之前停止它们,并将该数字发送到logcat以帮助调试有泄漏的应用程序。 - Martin Sykes
感谢@MartinSykes,这对于RAM密集型应用程序肯定是有帮助的。我相信它会因设备而异,一些像新的三星Galaxy S3可能允许24mb甚至48mb,特别是在使用largeHeap="true"时。 - Tom

6

我没有足够的声望在别人的答案下评论,但我认为Error 454的答案很接近。

我的应用程序也出现了类似的问题,应用程序重新启动时没有任何消息。我的问题是由于数组溢出引起的,在我的本地代码中,我试图访问n个对象数组中的索引n + 1。 JVM未报告错误也表明它是由您的本地代码引起的。

这个问题:c++ Jni Reference Table overflow 的错误日志与您的更新2非常相似,进一步表明您的错误在于未匹配您的获取和释放调用。

如果您不了解JNI pinned reference table是什么,我想引起您的注意,JNI规范标题为“访问Java对象”的部分,以及以下部分“访问原始数组”

最后,请提供您访问原始数据数组的本地代码片段,以帮助解决您的问题,但同时我想引起您对ReferenceTable overflow (max=512) JNI答案的最后一条评论的注意:

GetObjectArrayElement返回带有本地引用的对象,因此您需要删除本地引用。但是只有在完成数组元素时才应该这样做。因此,您应该在releaseIntArrayElements(oneDim)之后放置DeleteLocalRef(oneDim)

因此,请仔细检查您是否匹配了Get/Release调用,当您访问数组元素并且不再需要访问它时,删除本地引用。您可能会因为没有删除旧对象而达到JNI pinned reference table的末尾。请记住,JNI只是Java的C接口,因此您必须为本地代码协助垃圾收集。


当我在释放<type>ArrayElements之后尝试使用DeleteLocalRef时,我收到了多个“JNI WARNING: DeleteLocalRef(0x40536dc8) failed to find entry (valid=0)”消息,并且应用程序崩溃了... - Amit
我不使用GetObjectArrayElement(),而是使用GetByteArrayElement和GetShortArrayElement以及它们的Release方法... 如果不需要DeleteLocalRef,那么如何删除数组引用占用的内存(如果有)? - Amit
你在Release<PrimitiveType>ArrayElements调用的mode参数中使用了什么值?如果没有看到一些您的本地代码,我们无法提供更多帮助。展示您如何使用获取/释放方法以及在其间执行数据操作的代码片段将会很有用。 - n.collins
实际上,我通过阅读您的声明“如果应用程序崩溃并且没有提供任何信息,则表示其中存在一些JNI错误”,获得了信心...然后我进一步调试并阅读了更多关于Speex音频解码的内容...结果发现其中一个speex函数有时会返回意外值...我纠正了代码,到目前为止它还没有崩溃...谢谢,我还编辑了问题以在其中提及您的姓名...祝您愉快的一天... - Amit
@Amit,你说过在使用Release...ArrayElements时出现了JNI WARNING: DeleteLocalRef(0x40536dc8) failed to find entry (valid=0)的问题。我也遇到了同样的情况,因为我也在使用Speex,所以我们的代码中出现了相同的错误;大约一年前,当我引入释放代码后,我的崩溃问题得到了解决,但现在每个Speex帧都会出现这些烦人的日志信息。你解决了吗? - Schlangi

6
其他海报已经涵盖了关于内存不足的问题。我只想补充一点,为了调试你的本地代码,一个快速而且简单的方法就是在各个检查点处添加日志消息。以下是我的本地cpp文件之一的示例:
#include <android/log.h>

...

// Set to 1 to enable debug log traces...
#define DEBUG  0

#define LOG_TAG         "yourNativeCodeLogTag"
#if DEBUG
#define LOG_ERROR(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define LOG_WARN(...)   __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define LOG_INFO(...)   __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOG_DEBUG(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#else // if !DEBUG
#define LOG_ERROR(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define LOG_WARN(...)   __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define LOG_INFO(...)   
#define LOG_DEBUG(...) 
#endif // DEBUG

...

extern "C"
JNIEXPORT void JNICALL Java_com_whatever_package_YourClassName_jniInitializeLibrary(JNIEnv * env, jobject thiz, /* other irrelevant stuff here */)                 
{    
    LOG_DEBUG("Initializing native library.\n");
    ....
}

最后,你还需要在相关的*.mk文件中的LOCAL_LDLIBS变量中添加-llog。这样,你就可以从logcat中获得来自本地库的日志消息。
更新:看到您的更新后,我认为您应该使用上述技术将日志消息插入到本地encode()方法中,以精确定位其崩溃位置。

4
基于第二次更新,很清楚地表明您在JNI中未能解除数组的固定。这意味着您正在使用Get<Type>ArrayElements,但未能将1个或多个这些调用与Release<Type>ArrayElements匹配。
因此,ReferenceTable过载。请查找您正在调用Get而未调用Release的位置。例如,您可能正在调用GetIntArrayElements,但完成后未调用ReleaseIntArrayElements

我检查了我的JNI代码,它看起来是正确的,但应用程序仍然崩溃,而我以前没有遇到过这个错误。 - Amit

3
可能的问题之一是,您的应用程序可能会在 本地代码 中崩溃,这会突然停止您的应用程序,没有任何消息,并且在 Logcat 中没有任何输出。
我曾经遇到过同样的问题,尝试解码一些 位图 时,安卓系统在 本地代码 中崩溃并导致应用程序停止,而没有显示任何消息。
关于 onLowMemory(),@Tom 的回答已经涵盖了此问题。

我该如何发现本地代码中的崩溃?你是怎么做到的? - Amit
我真的不知道你如何调试本地代码... 我认为你需要从本地代码中添加一些日志。而我只是在logcat中看到了一些奇怪的错误。 - Ovidiu Latcu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接