안드로이드 앱의 충돌 방지에 한 일
보고서는 20 건 정도 있었지만, 대략 2 건의 대책을 했으므로 메모 해 둡니다
해결의 보증은 할 수 없기 때문에 나쁘지 않고
했던 일
TextInputEditText 구현 수정
MapView null 체크 추가
MapActivity.kt
override fun onDestroy() {
try {
binder?.mapView?.onDestroy()
} catch (e : NullPointerException) {
// Send report exception..
}
super.onDestroy()
}
충돌 보고서
GooglePlayConsole의 사이드바 '장애 및 ANR'에서 충돌 보고서를 확인할 수 있습니다.
이런 식으로 상당한 수가보고되었습니다.
많이 나와서 눈이 눈에 띄는 것 같습니다만, 대처할 수 있을 것 같은 것은 대략 2종류에 들어갔습니다
TextInputEditText 관련
setHint 주위의 예외
java.lang.NullPointerException:
at android.widget.Editor.stopTextActionMode (Editor.java:2687)
at android.widget.Editor.prepareCursorControllers (Editor.java:822)
at android.widget.TextView.nullLayouts (TextView.java:9153)
at android.widget.TextView.checkForRelayout (TextView.java:10101)
at android.widget.TextView.setHintInternal (TextView.java:6534)
at android.widget.TextView.setHint (TextView.java:6523)
at com.google.android.material.textfield.TextInputLayout.dispatchProvideAutofillStructure (TextInputLayout.java:1280)
at android.view.ViewGroup.dispatchProvideAutofillStructure (ViewGroup.java:3774)
at android.view.ViewGroup.dispatchProvideAutofillStructure (ViewGroup.java:3774)
at android.app.assist.AssistStructure$WindowNode.<init> (AssistStructure.java:517)
at android.app.assist.AssistStructure.<init> (AssistStructure.java:2047)
at android.app.ActivityThread.handleRequestAssistContextExtras (ActivityThread.java:3386)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1899)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loop (Looper.java:214)
at android.app.ActivityThread.main (ActivityThread.java:7050)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:965)
삼성 기기별 양식 길게 누르기 문제 라고 생각했지만, 미묘하게 다르게 보입니다.
(performLongClick이 얽혀 있지 않음)
그럼에도 불구하고 이번 충돌은 삼성 단말기였습니다.
AssistStructure$WindowNode 예외
java.lang.NullPointerException:
at android.app.assist.AssistStructure$WindowNode.<init> (AssistStructure.java:484)
at android.app.assist.AssistStructure.<init> (AssistStructure.java:1908)
at android.app.ActivityThread.handleRequestAssistContextExtras (ActivityThread.java:3040)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1812)
at android.os.Handler.dispatchMessage (Handler.java:105)
at android.os.Looper.loop (Looper.java:251)
at android.app.ActivityThread.main (ActivityThread.java:6563)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:240)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:767)
여기는 Android8 시스템 문제 와 같고, 실제로 Android8의 3 디바이스에서 발생하고 있었습니다
링크처의 기사를 쫓으면 알 수 있습니다만, 이쪽도 TextInputEditText 관련입니다
처치
이 블로그 기사 이나 상기 StackOverFlow에서도 언급되고 있습니다만,
java.lang.NullPointerException:
at android.widget.Editor.stopTextActionMode (Editor.java:2687)
at android.widget.Editor.prepareCursorControllers (Editor.java:822)
at android.widget.TextView.nullLayouts (TextView.java:9153)
at android.widget.TextView.checkForRelayout (TextView.java:10101)
at android.widget.TextView.setHintInternal (TextView.java:6534)
at android.widget.TextView.setHint (TextView.java:6523)
at com.google.android.material.textfield.TextInputLayout.dispatchProvideAutofillStructure (TextInputLayout.java:1280)
at android.view.ViewGroup.dispatchProvideAutofillStructure (ViewGroup.java:3774)
at android.view.ViewGroup.dispatchProvideAutofillStructure (ViewGroup.java:3774)
at android.app.assist.AssistStructure$WindowNode.<init> (AssistStructure.java:517)
at android.app.assist.AssistStructure.<init> (AssistStructure.java:2047)
at android.app.ActivityThread.handleRequestAssistContextExtras (ActivityThread.java:3386)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1899)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loop (Looper.java:214)
at android.app.ActivityThread.main (ActivityThread.java:7050)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:965)
java.lang.NullPointerException:
at android.app.assist.AssistStructure$WindowNode.<init> (AssistStructure.java:484)
at android.app.assist.AssistStructure.<init> (AssistStructure.java:1908)
at android.app.ActivityThread.handleRequestAssistContextExtras (ActivityThread.java:3040)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1812)
at android.os.Handler.dispatchMessage (Handler.java:105)
at android.os.Looper.loop (Looper.java:251)
at android.app.ActivityThread.main (ActivityThread.java:6563)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:240)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:767)
를 실시했습니다. 입력 양식 주위는 조금 불안정합니까?
게다가 별로 상관 없을지도 모르지만 setOnEditorActionListener를 무효화했습니다.
사용자 정보 입력 양식이 이번 문제였습니다만, 키보드의 엔터 버튼을 사용할 수 없어도 UX에 큰 영향은 없다고 판단했습니다
MapView 관련
java.lang.NullPointerException:
at com.google.maps.api.android.lib6.impl.cy.f (com.google.android.gms.dynamite_mapsdynamite@[email protected] (120400-0):1)
at com.google.android.gms.maps.internal.q.aX (com.google.android.gms.dynamite_mapsdynamite@[email protected] (120400-0):12)
at dt.onTransact (com.google.android.gms.dynamite_mapsdynamite@[email protected] (120400-0):4)
at android.os.Binder.transact (Binder.java:914)
at com.google.android.gms.internal.maps.zza.zzb (Unknown Source:20)
at com.google.android.gms.maps.internal.zzk.onDestroy (Unknown Source:26)
at com.google.android.gms.maps.MapView$zza.onDestroy (Unknown Source:34)
at com.google.android.gms.dynamic.DeferredLifecycleHelper.onDestroy (Unknown Source:71)
at com.google.android.gms.maps.MapView.onDestroy (Unknown Source:40)
at com.example.android.fragment.ExmapleFragment.onLowMemory (LastTripFragment.kt:231)
at androidx.fragment.app.Fragment.performLowMemory (Fragment.java:3069)
at androidx.fragment.app.FragmentManager.dispatchLowMemory (FragmentManager.java:3152)
at androidx.fragment.app.Fragment.performLowMemory (Fragment.java:3070)
at androidx.fragment.app.FragmentManager.dispatchLowMemory (FragmentManager.java:3152)
at androidx.fragment.app.FragmentController.dispatchLowMemory (FragmentController.java:379)
at androidx.fragment.app.FragmentActivity.onLowMemory (FragmentActivity.java:332)
at android.app.ActivityThread.handleLowMemory (ActivityThread.java:6002)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1921)
at android.os.Handler.dispatchMessage (Handler.java:107)
at android.os.Looper.loop (Looper.java:359)
at android.app.ActivityThread.main (ActivityThread.java:7418)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:935)
GoogleMap을 표시하는 MapView와 관련 Fragment의 라이프 사이클 시스템에서 다발하고 있습니다.
이 예에서는 onLowMemory이지만 onStart, onPause, onDestory 등에서도 비슷한 예외가 나왔습니다.
MapView 공식 문서 에서 언급했듯이 라이프 사이클과 MapView를 연결했지만 그 때 Map 객체가 존재하지 않는 것 같습니다.
API를 완전한 대화형 모드로 사용하는 경우 MapView 클래스에서 활동 수명 주기 메서드(onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy(), onSaveInstanceState() , onLowMemory())를 MapView 클래스의 해당 메서드로 전송해야 합니다.
ExampleFragment.kt
override fun onDestroy() {
binder.mapView.onDestroy() // ←ここでmapViewがnullになってる
super.onDestroy()
}
처치
이쪽에 대해서는 명확한 해결책을 찾을 수 없고, 우선 예외를 잡기로 했습니다↓
ExampleFragment.kt
override fun onDestroy() {
try {
binder.mapView.onDestroy()
} catch(e: Exception) {
/* do nothing */
}
super.onDestroy()
}
이제 먼저 모습을 살펴 보겠습니다.
tgkill
backtrace:
#00 pc 000000000006b970 /system/lib64/libc.so (tgkill+8)
#00 pc 0000000000068df4 /system/lib64/libc.so (pthread_kill+64)
#00 pc 0000000000024290 /system/lib64/libc.so (raise+24)
#00 pc 000000000001ccac /system/lib64/libc.so (abort+52)
#00 pc 000000000042cca8 /system/lib64/libart.so (art::Runtime::Abort()+352)
#00 pc 00000000000e4c24 /system/lib64/libart.so (art::LogMessage::~LogMessage()+1204)
#00 pc 000000000024ab24 /system/lib64/libart.so (art::IndirectReferenceTable::Add(unsigned int, art::mirror::Object*)+308)
#00 pc 0000000000324684 /system/lib64/libart.so (art::JNI::FindClass(_JNIEnv*, char const*)+2824)
크래시 리포트 중(안)에서도 한층 이채를 발하고 있는 것이 이쪽으로, linux의 시스템 콜일까? 생각합니다.
이것에 관해서는 스택 트레이스가 없기 때문에 원인 식별이 어려워, 또 꽤 한정된 디바이스로 밖에 나와 있지 않기 때문에 대응을 보답하고 있습니다
(Android7계의 낡은 디바이스로 나오는 것 같습니다)
요약
그래서 안드로이드 충돌 보고서에 대해 나름대로 대책을 넣어 보았습니다.
입력 양식과지도 당이 다소 불안정한 느낌입니다.
일단 이것으로 모습을 보자고 생각합니다.
Reference
이 문제에 관하여(안드로이드 앱의 충돌 방지에 한 일), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/nashitake/items/2dc8cf8c586d1de1545b텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)