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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
petitviolet
October 13, 2015
Technology
2.2k
1
Share
Hand-made Crash Report of Android Library
http://connpass.com/event/20240/
How to implement crash report of Android-Library
petitviolet
October 13, 2015
More Decks by petitviolet
See All by petitviolet
Stripeで請求書払い&銀行振込を実装する
petitviolet
1
1.6k
ピュアなドメインを支える技術/pure domain model and the technology behind it
petitviolet
14
11k
小さく始めるクラウドネイティブ/small start CloudNative
petitviolet
0
2.1k
2019年だからこそ12factor app/The Twelve-Factor app in 2019
petitviolet
1
1k
実践GraphQL on Scala/Real world GraphQL on Scala
petitviolet
8
3.4k
Kubernetesを知る/Introduction Kubernertes
petitviolet
1
690
GraphQL on Scala
petitviolet
3
2.8k
Microservices Batch on GAE
petitviolet
0
2k
Web API Design
petitviolet
18
8.6k
Other Decks in Technology
See All in Technology
プラットフォームエンジニアリングの実践 - AWS コンテナサービスで構築する社内プラットフォーム / AWS Containers Platform Meetup #1
literalice
1
230
Angular Architecture Revisited Modernizing Angular Architectural Patterns
rainerhahnekamp
0
120
ブラウザの投機的読み込みと投機ルールAPIを理解し、Webサービスのパフォーマンスを最適化する
shuta13
2
250
[Oracle TechNight#99] 生成AI時代のAI/ML入門 ~ AIとオラクルデータベースの関係 (前半)
oracle4engineer
PRO
1
170
ServiceNow Knowledge 26 の歩き方
manarobot
0
300
The 7 pitfalls of AI
ufried
0
170
UIライブラリに依存しすぎないReact Native設計を目指して
grandbig
0
190
要件定義の精度を高めるための型と生成AIの活用 / Using Types and Generative AI to Improve the Accuracy of Requirements Definition
haru860
0
270
QAエンジニアはどうやって プロダクト議論の場に入れるのか?
moritamasami
1
310
Claude Code を安全に使おう勉強会 / Claude Code Security Basics
masahirokawahara
12
39k
Keeping Ruby Running on Cygwin
fd0
0
200
需要創出(Chatwork)×供給(BPaaS) フライホイールとMoat 実行能力の最適配置とAI戦略
kubell_hr
0
1.8k
Featured
See All Featured
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
170
Accessibility Awareness
sabderemane
1
110
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.4k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
200
The agentic SEO stack - context over prompts
schlessera
0
770
Heart Work Chapter 1 - Part 1
lfama
PRO
6
35k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.9k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.2k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
The browser strikes back
jonoalderson
0
1k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
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εϨουͳΒࢮ͵ ͢ͰʹΫϥογϡͨ͠ޙͳΒࢮ͵
େࣄͳ͜ͱ • ϥΠϒϥϦΫϥογϡϩάΈͯվળ • ΞϓϦͷअຐΛ͠ͳ͍ • σϑΥϧτͷಈ࡞Λࡴ͞ͳ͍ • ϑϦʔζͤ͞ͳ͍Α͏ʹ •
ແݶΫϥογϡ͠ͳ͍Α͏ʹཧ • ໘Ͱϑϥάཧ