Android App Crashes Неожиданно во время работы?

Что делает мое приложение? Приложение, которое я разрабатываю, представляет собой типичное клиентское серверное приложение, которое ведет переговоры с сервером Windows с использованием Wi-Fi. Приложение имеет несколько видов деятельности и действительно имеет большую память и требования к процессору, т.е. собственные вызовы для кодирования / декодирования speex.

Какая у меня проблема? Проблема заключается в том, что приложение неожиданно запускается, работая абсолютно нормально. Иногда, работая нормально, я вижу (в logcat), что класс конструктора приложения (класс, который расширяет класс приложений API). Это сбой моего приложения, поскольку все глобальные данные хранятся в самом классе приложения.

Что я наделал ? Первое, что поразило меня, было то, что Android может чувствовать, что у них низкая память, поэтому он прекращает мое приложение и перезапускает его автоматически. Поэтому я реализовал onLowMemory() класса Application. Но, к моему удивлению, его никогда не называют ..

В чем главная проблема? Основная проблема заключается в том, Nothing is printed on LogCat . Похоже, что даже сам Android не знает, почему он перезапустил уже запущенное приложение?

Какова возможная причина этого внезапного перезапуска? Как я могу избежать этого?

Я работаю над Galaxy Y, а версия API – 2.3.6. Мой AndroidManifiest.xml выглядит так:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.argusoft.roobrooAndroid" 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> 

EDIT Я только что увидел следующий результат в LogCat после использования CheckJNI,

 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 … Помощь действительно нужна ….

UPDATE 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 com.argusoft.roobrooAndroid.speex.SpeexEncoder.encode(Native Method) 06-29 12:07:28.406: I/dalvikvm(19308): at com.argusoft.roobrooAndroid.speex.SpeexEncoder.encodeFrame(SpeexEncoder.java:51) 06-29 12:07:28.406: I/dalvikvm(19308): at com.argusoft.roobrooAndroid.models.Session.capturedAudioReceived(Session.java:656) 06-29 12:07:28.406: I/dalvikvm(19308): at com.argusoft.roobrooAndroid.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 com.argusoft.roobrooAndroid.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 com.argusoft.roobrooAndroid.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 com.argusoft.roobrooAndroid.modules.AudioPlayer.onPeriodicNotification(AudioPlayer.java:163) 

Решение Хорошо тестирование по-прежнему включено для измененного кода, и все кажется позитивным до сих пор. Проблема была внутри JNI (я думаю). @ N.Collins statement «Тот факт, что JVM не сообщает об ошибке, также указывает на то, что она вызвана вашим собственным кодом». Был одним из самых правильных указателей на решение. Я действительно благодарю всех людей, которые отвечали, что это действительно помогло мне в той или иной форме. Я фактически удалил множество других ошибок, пытаясь решить эту проблему всем благодаря сообществу.

Solutions Collecting From Web of "Android App Crashes Неожиданно во время работы?"

Основываясь на обновлении №2, довольно ясно, что вам не удалось открепить массив в вашем JNI. Это означает, что вы используете Get<Type>ArrayElements и не смогли выполнить 1 или более из этих вызовов с Release<Type>ArrayElements .

В результате эталонная таблица переполнена. Ищите места, где вы вызываете Get и не вызываете Release. Например, вы можете вызвать GetIntArrayElements но не ReleaseIntArrayElements вызвать ReleaseIntArrayElements когда закончите.

Трудно сказать без полного исходного кода, что именно происходит, но, возможно, ответ Ромен Гай здесь, в Google Groups, поможет.

onLowMemory() вызывается, когда вся система onLowMemory() из памяти, а не когда ваш процесс заканчивается из памяти. Каждое приложение ограничено фиксированным объемом ОЗУ (например, 24 МБ на Nexus One). Если вы используете эти 24 МБ, но система все еще имеет больше доступной оперативной памяти, вы получите OutOfMemoryError но не onLowMemory() .

Предел 24 МБ в значительной степени установлен в камне для приложений на <Honeycomb. Если вы ориентируетесь на API 11 или выше, вы можете запросить больше памяти, объявив, что для вашего приложения будет выделена большая куча. Он не упоминается в документации, но добавление android:largeHeap="true" в ваш тег application в вашем Manifest.xml сделает это (хотя это не гарантируется).

Примечание: на модифицированной прошивке (пользовательские ПЗУ) это значение может быть ниже или выше. Я считаю, что на Galaxy Nexus Samsung по умолчанию 48 МБ, но, как правило, пребывание в пределах 24 МБ является безопасным предположением. В Sony Ericsson есть отличная статья, объясняющая технические различия между Gingerbread и Ice Cream Sandwich (оперативная память – это тема, которая подробно освещена).

Удачи, надеюсь, это по крайней мере поможет вам отследить проблему.

Другие плакаты покрывали проблемы с памятью. Я просто добавлю, что для отладки собственного кода одним быстрым и грязным способом является добавление сообщений журнала на разных контрольных точках. Вот пример из одного из моих родных файлов 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"); .... } 

Наконец, вам также нужно будет добавить -llog в вашу переменную LOCAL_LDLIBS в соответствующем файле *.mk . Затем вы можете получать сообщения журнала из своей родной библиотеки в logcat.

ОБНОВЛЕНИЕ. После просмотра ваших обновлений, я думаю, вы должны использовать описанную выше технику, чтобы перенести сообщения журнала в свой собственный метод encode() чтобы увидеть, где именно происходит сбой.

У меня недостаточно комментариев, чтобы прокомментировать ответы других людей, но я думаю, что ответ Error 454 довольно близок.

У меня была аналогичная проблема с моим собственным приложением с перезапуском приложения без сообщения. Моя проблема была вызвана переполнением массива, когда я пытался получить доступ к индексу n+1 в массиве из n объектов в моем собственном коде. Тот факт, что JVM не сообщает об ошибке, также указывает на то, что она вызвана вашим собственным кодом.

Этот вопрос: c ++ Jni Reference Table overflow имеет очень похожий журнал ошибок к вашему обновлению 2, что еще раз указывает на то, что ваша ошибка заключается в том, что вы не соответствовали вашим запросам на получение и освобождение.

Если вы не понимаете, что указано в JNI pinned reference table , я хотел бы обратить ваше внимание на разделы спецификации JNI под названием «Доступ к объектам Java» и следующий раздел «Доступ к примитивным массивам» .

Наконец, некоторые фрагменты вашего собственного кода, в которых вы обращаетесь к примитивным массивам данных, были бы полезны для решения вашей проблемы, но в то же время я хотел бы обратить ваше внимание на окончательный комментарий к ответу на переполнение ReferenceTable (max = 512) JNI Который гласит:

GetObjectArrayElement возвращает объект с локальной ссылкой на него, поэтому вам нужно удалить локальную ссылку. Но вы должны это делать только тогда, когда вы закончите с элементами массива. Поэтому вы должны поместить DeleteLocalRef(oneDim) после releaseIntArrayElements(oneDim) .

Поэтому, пожалуйста, дважды проверьте, что вы отвечали на вызовы Get / Release при доступе к элементам массива и, когда вам больше не нужен доступ к нему, удалите локальную ссылку . Возможно, вы попали в конец таблицы ссылок, поддерживаемой JNI, потому что вы не удаляете старые объекты. Помните, JNI – это просто интерфейс для Java, поэтому вам нужно помочь в сборке мусора для вашего собственного кода.

Одна вещь, которая может быть проблемой, заключается в том, что, возможно, ваше приложение сработает где-то внутри native code и это внезапно остановит ваше приложение без какого-либо сообщения, и ничего не будет напечатано в Logcat .

У меня была та же проблема, пытаясь декодировать некоторые bitmaps , а андроид сработал где-то внутри native code и приложение останавливается, не вызывая никакого сообщения.

Что касается onLowMemory() Ответы @Tom покрывают его.