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
2k
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
790
ピュアなドメインを支える技術/pure domain model and the technology behind it
petitviolet
14
9.4k
小さく始めるクラウドネイティブ/small start CloudNative
petitviolet
0
1.6k
2019年だからこそ12factor app/The Twelve-Factor app in 2019
petitviolet
1
920
実践GraphQL on Scala/Real world GraphQL on Scala
petitviolet
8
2.7k
Kubernetesを知る/Introduction Kubernertes
petitviolet
1
560
GraphQL on Scala
petitviolet
3
2.4k
Microservices Batch on GAE
petitviolet
0
1.8k
Web API Design
petitviolet
18
7.6k
Other Decks in Technology
See All in Technology
クラウドサインにおけるプロダクトマネージャーの役割と開発プロセス / 20240410_cloudsign-PdM
bengo4com
1
680
プロトタイピングによる不確実性の低減 / Reducing Uncertainty through Prototyping
ohbarye
3
240
Terraformあれやこれ/terraform-this-and-that
emiki
4
450
レガシーをぶっ壊せ。AEONで始めるDevRelの話 / Qiita Night 2024-2-22
aeonpeople
3
150
Delivering Millions of Messages within seconds @ Duolingo
pelelgrino
0
330
現代CSSフレームワークの内部実装とその仕組み
poteboy
2
540
コードを書く隙間を見つけて生きていく技術/Findy 思考の現在地
fujiwara3
24
5.2k
20240416_devopsdaystokyo
kzkmaeda
1
190
プロデザ! BY リクルート vol.18_リクルートのリサーチ実践組織「リサーチブーストコミュニティ」
recruitengineers
PRO
3
240
自動生成を活用した、運用保守コストを抑える Error/Alert/Runbook の一元集約管理 / Centralized management of Error/Alert/Runbook to minimize operational costs using automated code generation
biwashi
9
2.1k
Next'24 事例セッションの紹介とクラウド資格を活用したキャリア形成について語りMuscle
yasumuusan
1
340
開発生産性向上サービスを作るFindyが自分たちで開発生産性を爆上げした組織づくりの歩み / Findy's path to boosting its own development productivity 2024-04-17
ma3tk
3
340
Featured
See All Featured
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
34
8.9k
What’s in a name? Adding method to the madness
productmarketing
PRO
15
2.6k
What's new in Ruby 2.0
geeforr
337
31k
Typedesign – Prime Four
hannesfritz
36
2.1k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
60
14k
Optimising Largest Contentful Paint
csswizardry
7
2.3k
Building a Modern Day E-commerce SEO Strategy
aleyda
16
6.4k
GraphQLとの向き合い方2022年版
quramy
31
12k
A Philosophy of Restraint
colly
196
16k
Designing with Data
zakiwarfel
95
4.8k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
356
22k
Facilitating Awesome Meetings
lara
41
5.6k
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εϨουͳΒࢮ͵ ͢ͰʹΫϥογϡͨ͠ޙͳΒࢮ͵
େࣄͳ͜ͱ • ϥΠϒϥϦΫϥογϡϩάΈͯվળ • ΞϓϦͷअຐΛ͠ͳ͍ • σϑΥϧτͷಈ࡞Λࡴ͞ͳ͍ • ϑϦʔζͤ͞ͳ͍Α͏ʹ •
ແݶΫϥογϡ͠ͳ͍Α͏ʹཧ • ໘Ͱϑϥάཧ