Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Hand-made Crash Report of Android Library
Search
petitviolet
October 13, 2015
Technology
1
2.1k
Hand-made Crash Report of Android Library
http://connpass.com/event/20240/
How to implement crash report of Android-Library
petitviolet
October 13, 2015
Tweet
Share
More Decks by petitviolet
See All by petitviolet
Stripeで請求書払い&銀行振込を実装する
petitviolet
0
1.2k
ピュアなドメインを支える技術/pure domain model and the technology behind it
petitviolet
14
9.9k
小さく始めるクラウドネイティブ/small start CloudNative
petitviolet
0
1.8k
2019年だからこそ12factor app/The Twelve-Factor app in 2019
petitviolet
1
970
実践GraphQL on Scala/Real world GraphQL on Scala
petitviolet
8
2.9k
Kubernetesを知る/Introduction Kubernertes
petitviolet
1
620
GraphQL on Scala
petitviolet
3
2.6k
Microservices Batch on GAE
petitviolet
0
1.9k
Web API Design
petitviolet
18
8.2k
Other Decks in Technology
See All in Technology
UI State設計とテスト方針
rmakiyama
2
290
フロントエンド設計にモブ設計を導入してみた / 20241212_cloudsign_TechFrontMeetup
bengo4com
0
1.9k
[Ruby] Develop a Morse Code Learning Gem & Beep from Strings
oguressive
1
150
非機能品質を作り込むための実践アーキテクチャ
knih
2
630
継続的にアウトカムを生み出し ビジネスにつなげる、 戦略と運営に対するタイミーのQUEST(探求)
zigorou
0
500
How to be an AWS Community Builder | 君もAWS Community Builderになろう!〜2024 冬 CB募集直前対策編?!〜
coosuke
PRO
2
2.8k
watsonx.ai Dojo #5 ファインチューニングとInstructLAB
oniak3ibm
PRO
0
160
Jetpack Composeで始めるServer Cache State
ogaclejapan
2
160
Kubeshark で Kubernetes の Traffic を眺めてみよう/Let's Look at k8s Traffic with Kubeshark
kota2and3kan
3
370
OpenShift Virtualizationのネットワーク構成を真剣に考えてみた/OpenShift Virtualization's Network Configuration
tnk4on
0
130
.NET 9 のパフォーマンス改善
nenonaninu
0
360
大幅アップデートされたRagas v0.2をキャッチアップ
os1ma
2
520
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
95
17k
StorybookのUI Testing Handbookを読んだ
zakiyama
27
5.3k
Adopting Sorbet at Scale
ufuk
73
9.1k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.9k
Scaling GitHub
holman
458
140k
The Language of Interfaces
destraynor
154
24k
The Cult of Friendly URLs
andyhume
78
6.1k
RailsConf 2023
tenderlove
29
940
The Invisible Side of Design
smashingmag
298
50k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.2k
Designing for humans not robots
tammielis
250
25k
How to Think Like a Performance Engineer
csswizardry
22
1.2k
Transcript
Hand-made CrashReport of Android Library potatotips #22 @petitviolet
About me • @petitviolet • Fringe81 Co., Ltd. • ࠂSDKͷAndroid/iOS։ൃ
• ࠷ۙScalaॻ͍ͯ·͢
ΫϥογϡϨϙʔτ
None
CrashReport • ΞϓϦέʔγϣϯ͕Ϋϥογϡͨ࣌͠ͷঢ়گ ΛϨϙʔτͱͯ͠ૹ৴ • ͷछྨ • OS • ελοΫτϨʔε
• etc.
crashlytics https://try.crashlytics.com/
ACRA https://github.com/ACRA/acra
Desire • ϥΠϒϥϦىҼͷΫϥογϡϩάऩू͍ͨ͠ • ΞϓϦͷΫϥογϡϩάऩू͠ͳ͍ • ͦΕCrashlyticsʹ͓ͤ • ಠࣗͷσʔλ͕ཉ͍͠
UncaughtException • (جຊతʹ)Ϋϥογϡ͢Δͱ͖ʹඈͿྫ֎ • catch͞Εͳ͔ͬͨͷͰuncaught • ErrorͰͳ͘Exception
UncaughtExceptionHandler • UncaughtExceptionΛͲ͏ѻ͏͔ • σϑΥϧτͷಈ࡞ getDefaultUncaughtExceptionHandler • Defaultͷಈ࡞Λյ͞ͳ͍ͨΊʹอଘ
جຊ෦ class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { private static final
String PACKAGE_NAME = BuildConfig.APPLICATION_ID; private final Thread.UncaughtExceptionHandler mDefaultHandler; private WeakReference<Context> mContext; volatile private static boolean sCrashing = false; public MyUncaughtExceptionHandler(Context context) { mContext = new WeakReference<>(context.getApplicationContext()); mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); } }
جຊ෦ class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { private static final
String PACKAGE_NAME = BuildConfig.APPLICATION_ID; private final Thread.UncaughtExceptionHandler mDefaultHandler; private WeakReference<Context> mContext; volatile private static boolean sCrashing = false; public MyUncaughtExceptionHandler(Context context) { mContext = new WeakReference<>(context.getApplicationContext()); mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); } } UncaughtExceptionHandlerΛܧঝ
جຊ෦ class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { private static final
String PACKAGE_NAME = BuildConfig.APPLICATION_ID; private final Thread.UncaughtExceptionHandler mDefaultHandler; private WeakReference<Context> mContext; volatile private static boolean sCrashing = false; public MyUncaughtExceptionHandler(Context context) { mContext = new WeakReference<>(context.getApplicationContext()); mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); } } DefaultͷUncaughtExceptionHandlerΛอଘ UncaughtExceptionHandlerΛܧঝ
جຊ෦ @Override public void uncaughtException(final Thread thread, final Throwable ex)
{ if (sCrashing) { mDefaultHandler.uncaughtException(thread, ex); return; } sCrashing = true; StackTraceElement[] stackTraceElements = ex.getStackTrace(); boolean inLibraryException = false; for (StackTraceElement stackTraceElement : stackTraceElements) { if (stackTraceElement.getClassName().contains(PACKAGE_NAME)) { inLibraryException = true; break; } } // ϥΠϒϥϦͰͷΫϥογϡͩͬͨ߹ϩάΛૹΔ if (inLibraryException) { try { sendCrashReport(ex); } catch (Exception e) { e.printStackTrace(); } } // ϝΠϯεϨουͩͬͨ߹ࢮ͵͔͠ແ͍ if (thread.getId() == Looper.getMainLooper().getThread().getId() || !inLibraryException) { mDefaultHandler.uncaughtException(thread, ex); } }
@Override public void uncaughtException(final Thread thread, final Throwable ex) {
if (sCrashing) { mDefaultHandler.uncaughtException(thread, ex); return; } sCrashing = true; StackTraceElement[] stackTraceElements = ex.getStackTrace(); boolean inLibraryException = false; for (StackTraceElement stackTraceElement : stackTraceElements) { if (stackTraceElement.getClassName().contains(PACKAGE_NAME)) { inLibraryException = true; break; } } ͢ͰʹΫϥογϡͨ͠ޙͳΒࢮ͵
@Override public void uncaughtException(final Thread thread, final Throwable ex) {
if (sCrashing) { mDefaultHandler.uncaughtException(thread, ex); return; } sCrashing = true; StackTraceElement[] stackTraceElements = ex.getStackTrace(); boolean inLibraryException = false; for (StackTraceElement stackTraceElement : stackTraceElements) { if (stackTraceElement.getClassName().contains(PACKAGE_NAME)) { inLibraryException = true; break; } } ͢ͰʹΫϥογϡͨ͠ޙͳΒࢮ͵ LibraryͷΫϥογϡ͔Ͳ͏͔ఆ
// ϥΠϒϥϦͰͷΫϥογϡͩͬͨ߹ϩάΛૹΔ if (inLibraryException) { try { sendCrashReport(ex); } catch
(Exception e) { e.printStackTrace(); } } // ϝΠϯεϨουͩͬͨ߹ࢮ͵͔͠ແ͍ if (thread.getId() == Looper.getMainLooper().getThread().getId() || !inLibraryException) { mDefaultHandler.uncaughtException(thread, ex); } }
// ϥΠϒϥϦͰͷΫϥογϡͩͬͨ߹ϩάΛૹΔ if (inLibraryException) { try { sendCrashReport(ex); } catch
(Exception e) { e.printStackTrace(); } } // ϝΠϯεϨουͩͬͨ߹ࢮ͵͔͠ແ͍ if (thread.getId() == Looper.getMainLooper().getThread().getId() || !inLibraryException) { mDefaultHandler.uncaughtException(thread, ex); } } LibraryͷΫϥογϡͳΒϩάૹ৴
// ϥΠϒϥϦͰͷΫϥογϡͩͬͨ߹ϩάΛૹΔ if (inLibraryException) { try { sendCrashReport(ex); } catch
(Exception e) { e.printStackTrace(); } } // ϝΠϯεϨουͩͬͨ߹ࢮ͵͔͠ແ͍ if (thread.getId() == Looper.getMainLooper().getThread().getId() || !inLibraryException) { mDefaultHandler.uncaughtException(thread, ex); } } Library֎ͷΫϥογϡ͔UIεϨουͳΒࢮ͵ LibraryͷΫϥογϡͳΒϩάૹ৴
جຊ෦ @Override public void uncaughtException(final Thread thread, final Throwable ex)
{ if (sCrashing) { mDefaultHandler.uncaughtException(thread, ex); return; } sCrashing = true; StackTraceElement[] stackTraceElements = ex.getStackTrace(); boolean inLibraryException = false; for (StackTraceElement stackTraceElement : stackTraceElements) { if (stackTraceElement.getClassName().contains(PACKAGE_NAME)) { inLibraryException = true; break; } } // ϥΠϒϥϦͰͷΫϥογϡͩͬͨ߹ϩάΛૹΔ if (inLibraryException) { try { sendCrashReport(ex); } catch (Exception e) { e.printStackTrace(); } } // ϝΠϯεϨουͩͬͨ߹ࢮ͵͔͠ແ͍ if (thread.getId() == Looper.getMainLooper().getThread().getId() || !inLibraryException) { mDefaultHandler.uncaughtException(thread, ex); } } LibraryͷΫϥογϡ͔Ͳ͏͔ఆ LibraryͷΫϥογϡͳΒϩάૹ৴ Library֎ͷΫϥογϡ͔UIεϨουͳΒࢮ͵ ͢ͰʹΫϥογϡͨ͠ޙͳΒࢮ͵
େࣄͳ͜ͱ • ϥΠϒϥϦΫϥογϡϩάΈͯվળ • ΞϓϦͷअຐΛ͠ͳ͍ • σϑΥϧτͷಈ࡞Λࡴ͞ͳ͍ • ϑϦʔζͤ͞ͳ͍Α͏ʹ •
ແݶΫϥογϡ͠ͳ͍Α͏ʹཧ • ໘Ͱϑϥάཧ