Hand-made Crash Report of Android Library

93bc8fb48f57c11e417dad9d26a2fb8a?s=47 petitviolet
October 13, 2015

Hand-made Crash Report of Android Library

http://connpass.com/event/20240/
How to implement crash report of Android-Library

93bc8fb48f57c11e417dad9d26a2fb8a?s=128

petitviolet

October 13, 2015
Tweet

Transcript

  1. Hand-made CrashReport of Android Library potatotips #22 @petitviolet

  2. About me • @petitviolet • Fringe81 Co., Ltd. • ޿ࠂSDKͷAndroid/iOS։ൃ

    • ࠷ۙ͸Scalaॻ͍ͯ·͢
  3. ΫϥογϡϨϙʔτ

  4. None
  5. CrashReport • ΞϓϦέʔγϣϯ͕Ϋϥογϡͨ࣌͠ͷঢ়گ ΛϨϙʔτͱͯ͠ૹ৴ • ୺຤ͷछྨ • OS • ελοΫτϨʔε

    • etc.
  6. crashlytics https://try.crashlytics.com/

  7. ACRA https://github.com/ACRA/acra

  8. Desire • ϥΠϒϥϦىҼͷΫϥογϡϩά΋ऩू͍ͨ͠ • ΞϓϦͷΫϥογϡϩά͸ऩू͠ͳ͍ • ͦΕ͸Crashlytics౳ʹ͓೚ͤ • ಠࣗͷσʔλ͕ཉ͍͠

  9. UncaughtException • (جຊతʹ)Ϋϥογϡ͢Δͱ͖ʹඈͿྫ֎ • catch͞Εͳ͔ͬͨͷͰuncaught • ErrorͰ͸ͳ͘Exception

  10. UncaughtExceptionHandler • UncaughtExceptionΛͲ͏ѻ͏͔ • σϑΥϧτͷಈ࡞͸ getDefaultUncaughtExceptionHandler • Defaultͷಈ࡞Λյ͞ͳ͍ͨΊʹอଘ

  11. جຊ෦෼ 
 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();
 }
 }
  12. جຊ෦෼ 
 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Λܧঝ
  13. جຊ෦෼ 
 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Λܧঝ
  14. جຊ෦෼ @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);
 }
 }
  15. @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;
 }
 } ͢ͰʹΫϥογϡͨ͠ޙͳΒࢮ͵
  16. @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಺ͷΫϥογϡ͔Ͳ͏͔൑ఆ
  17. // ϥΠϒϥϦ಺ͰͷΫϥογϡͩͬͨ৔߹͸ϩάΛૹΔ
 if (inLibraryException) {
 try {
 sendCrashReport(ex);
 } catch

    (Exception e) {
 e.printStackTrace();
 }
 }
 
 // ϝΠϯεϨουͩͬͨ৔߹͸ࢮ͵͔͠ແ͍
 if (thread.getId() == Looper.getMainLooper().getThread().getId() || !inLibraryException) {
 mDefaultHandler.uncaughtException(thread, ex);
 }
 }
  18. // ϥΠϒϥϦ಺ͰͷΫϥογϡͩͬͨ৔߹͸ϩάΛૹΔ
 if (inLibraryException) {
 try {
 sendCrashReport(ex);
 } catch

    (Exception e) {
 e.printStackTrace();
 }
 }
 
 // ϝΠϯεϨουͩͬͨ৔߹͸ࢮ͵͔͠ແ͍
 if (thread.getId() == Looper.getMainLooper().getThread().getId() || !inLibraryException) {
 mDefaultHandler.uncaughtException(thread, ex);
 }
 } Library಺ͷΫϥογϡͳΒϩάૹ৴
  19. // ϥΠϒϥϦ಺ͰͷΫϥογϡͩͬͨ৔߹͸ϩάΛૹΔ
 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಺ͷΫϥογϡͳΒϩάૹ৴
  20. جຊ෦෼ @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εϨουͳΒࢮ͵ ͢ͰʹΫϥογϡͨ͠ޙͳΒࢮ͵
  21. େࣄͳ͜ͱ • ϥΠϒϥϦ΋ΫϥογϡϩάΈͯվળ • ΞϓϦͷअຐΛ͠ͳ͍ • σϑΥϧτͷಈ࡞Λࡴ͞ͳ͍ • ϑϦʔζͤ͞ͳ͍Α͏ʹ •

    ແݶΫϥογϡ͠ͳ͍Α͏ʹ؅ཧ • ໘౗Ͱ΋ϑϥά؅ཧ