$30 off During Our Annual Pro Sale. View Details »

Build my own debugging tool on overlay

Build my own debugging tool on overlay

Keishin Yokomaku

March 10, 2017
Tweet

More Decks by Keishin Yokomaku

Other Decks in Technology

Transcript

  1. BUILDING MY OWN DEBUGGING TOOL ON OVERLAY Keishin Yokomaku /

    DroidKaigi 2017 DAY.02 - Room 2
  2. Building my own debugging tool on overlay About me ▸

    ԣນܓਅ (Keishin Yokomaku) ▸ Drivemode, Inc. / ΤϯδχΞ ▸ KeithYokoma: GitHub / Twitter / Ωʔλ / Stack Overflow ▸ Books: Android ΞΧσϛΞ / AZ ҟຊ / ͳͳ͍Ζ Android ▸ Fun: ثցମૢ / ࣗసं / ࣸਅ / ےτϨ / / ▸ Today’s Quote: “Happy DroidKaigi!” 2
  3. BUILDING MY OWN DEBUGGING TOOL ON OVERLAY

  4. Building my own debugging tool on overlay ͍͞͠ΐʹ ▸ ͜ͷτʔΫʹ͸एׯͷࠇຐज़త಺༰ؚ͕·Ε͍ͯ·͢

    ▸ Ԡ༻͢Δ৔߹ɺ༻๏༻ྔΛकָ͓ͬͯ͘͠࢖͍͍ͩ͘͞ 4
  5. Building my own debugging tool on overlay 5

  6. Building my own debugging tool on overlay ͜Ε͸Կʁ ▸ ৗʹखલʹදࣔ͞Εଓ͚Δ

    View ▸ ։ൃऀΦϓγϣϯ ▸ ͲͷΞϓϦΛ։͍͍ͯͯ΋ݟ͑Δ ▸ ఆظతʹ৘ใ͕ߋ৽͞Εଓ͚Δ 6
  7. Building my own debugging tool on overlay ͜Ε͸Կʁ ▸ ৗʹखલʹදࣔ͞Εଓ͚Δ

    View ▸ ։ൃऀΦϓγϣϯ ▸ ͲͷΞϓϦΛ։͍͍ͯͯ΋ݟ͑Δ ▸ ఆظతʹ৘ใ͕ߋ৽͞Εଓ͚Δ 7 ࣗ෼Ͱ࡞Γ͍ͨ
  8. Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ

    ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 8
  9. Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ

    ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 9
  10. Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ

    ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 10
  11. Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ

    ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 11
  12. Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ

    ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 12
  13. Building my own debugging tool on overlay ຊ୊ʹೖΔલʹ ▸ DroidKaigi

    ΞϓϦʹαϯϓϧ࣮૷Λ૊ΈࠐΈ·ͨ͠ ▸ ϦϙδτϦ: http://bit.ly/2lGA6Aj ▸ ઃఆ -> Developer Menu -> Debug Overlay View ▸ ݴޠઃఆΛมߋͨ͠Γɺը໘ճస͢Δͱ… 13
  14. ಛผͳϨΠϠʹ VIEW Λදࣔ͢Δ

  15. Building my own debugging tool on overlay ొ৔͢ΔΫϥε ▸ android.view.WindowManager

    ▸ γεςϜαʔϏε ▸ View Λ௥Ճɾ࡟আɾߋ৽͢ΔϝιουΛ΋ͭ ▸ android.view.WindowManager.LayoutParams ▸ WindowManager Ͱඳը͢Δ View ͷͨΊͷύϥϝʔλ 15
  16. Building my own debugging tool on overlay ొ৔͢ΔΫϥε ▸ android.view.WindowManager

    ▸ γεςϜαʔϏε ▸ View Λ௥Ճɾ࡟আɾߋ৽͢ΔϝιουΛ΋ͭ ▸ android.view.WindowManager.LayoutParams ▸ WindowManager Ͱඳը͢Δ View ͷͨΊͷύϥϝʔλ 16
  17. Building my own debugging tool on overlay ొ৔͢ΔΫϥε ▸ android.view.WindowManager

    ▸ γεςϜαʔϏε ▸ View Λ௥Ճɾ࡟আɾߋ৽͢ΔϝιουΛ΋ͭ ▸ android.view.WindowManager.LayoutParams ▸ WindowManager Ͱඳը͢Δ View ͷͨΊͷύϥϝʔλ 17
  18. Building my own debugging tool on overlay WindowManager ͱύʔϛογϣϯ ▸

    ಛผͳύʔϛογϣϯ ▸ “ଞͷΞϓϦʹॏͶͯදࣔ” ▸ <uses-permission> ▸ android.permission.SYSTEM_ALERT_WINDOW ▸ Πϯετʔϧ࣌ʹࣗಈͰڐՄ͞ΕΔ ▸ ͋ͱͰڐՄΛऔΓԼ͛Δ͜ͱ͕Ͱ͖Δ 18
  19. Building my own debugging tool on overlay WindowManager ͱύʔϛογϣϯ ▸

    ઃఆը໘Λ։͘ Intent ͷΞΫγϣϯ ▸ android.settings.action.MANAGE_OVERLAY_PERMISSIO N ▸ ڐՄ͕͋Δ͔Ͳ͏͔νΣοΫ͢Δϝιου ▸ Settings.canDrawOverlays(Context) ▸ ύʔϛογϣϯΛऔͬͨΞϓϦͷϓϩηε͕ੜ͖͍ͯΔͱɺ ଞͷΞϓϦͷΠϯετʔϧϘλϯ͕ԡͤͳ͘ͳΔ͜ͱʹ஫ҙ 19
  20. Building my own debugging tool on overlay WindowManager ͷϝιου ▸

    WindowManager#addView(View, LayoutParams) ▸ View ͷ௥Ճ ▸ WindowManager#removeView(View) ▸ View ͷ࡟আ ▸ WindowManager#updateViewLayout(View, LayoutParams) ▸ View ͷύϥϝʔλߋ৽ 20
  21. Building my own debugging tool on overlay WindowManager Ͱ࢖͏ύϥϝʔλ ▸

    WindowManager.LayoutParams ▸ ॎɾԣͷαΠζ ▸ ϨΠϠ ▸ ϑϥά ▸ ϐΫηϧϑΥʔϚοτ 21
  22. Building my own debugging tool on overlay WindowManager ͷϨΠϠ 22

    TYPE_WALLPAPER TYPE_APPLICATION TYPE_PHONE TYPE_SYSTEM_DIALOG TYPE_TOAST TYPE_SYSTEM_ALERT TYPE_INPUT_METHOD TYPE_KEYGUARD_DIALOG TYPE_SYSTEM_OVERLAY TYPE_SYSTEM_ERROR
  23. Building my own debugging tool on overlay WindowManager ͷϨΠϠ 23

    TYPE_WALLPAPER TYPE_APPLICATION TYPE_PHONE TYPE_SYSTEM_DIALOG TYPE_TOAST TYPE_SYSTEM_ALERT TYPE_INPUT_METHOD TYPE_KEYGUARD_DIALOG TYPE_SYSTEM_OVERLAY TYPE_SYSTEM_ERROR ଟ͗͢Δ
  24. Building my own debugging tool on overlay (ଟ෼)Α͘࢖͏WindowManager ͷϨΠϠ 24

    TYPE_SYSTEM_DIALOG TYPE_SYSTEM_ALERT TYPE_SYSTEM_OVERLAY TYPE_APPLICATION
  25. Building my own debugging tool on overlay (ଟ෼)Α͘࢖͏WindowManager ͷϨΠϠ ▸

    TYPE_SYSTEM_OVERLAY ▸ ϩοΫը໘ͷ্ɻλονΠϕϯτΛरͬͯ͸μϝɻ ▸ TYPE_SYSTEM_ALERT ▸ Toast ΑΓ΋্ɻ ▸ TYPE_SYSTEM_DIALOG ▸ ΞϓϦέʔγϣϯΑΓ΋্ɻ 25
  26. Building my own debugging tool on overlay WindowManager ͷϑϥά ▸

    WindowManager ʹ௥Ճ͢Δ View ͷৼΔ෣͍ΛܾΊΔ ▸ λονΠϕϯτ΍ϑΥʔΧεͷऔಘΛ͢Δ͔Ͳ͏͔ ▸ ྖҬ֎΁ͷඳըͷՄ൱ 26
  27. Building my own debugging tool on overlay λονΠϕϯτ΍ϑΥʔΧεͷϑϥά ▸ FLAG_NOT_FOCUSABLE

    ▸ ϑΥʔΧεΛୣΘͳ͍ ▸ FLAG_NOT_TOUCH_MODAL ΋ࣗಈͰ௥Ճ͞ΕΔ ▸ FLAG_NOT_TOUCH_MODAL ▸ WindowManager ʹ௥Ճͨ͠ View ͷྖҬ֎ͷλονΠϕ ϯτΛഎޙͷΞϓϦʹྲྀ͢ 27
  28. Building my own debugging tool on overlay λονΠϕϯτ΍ϑΥʔΧεͷϑϥά ▸ FLAG_NOT_TOUCHABLE

    ▸ λονΠϕϯτΛ͢΂ͯഎޙͷΞϓϦʹྲྀ͢ 28
  29. Building my own debugging tool on overlay ྖҬ֎΁ͷඳըͷՄ൱ΛܾΊΔϑϥά ▸ FLAG_LAYOUT_IN_SCREEN

    ▸ ը໘ͷαΠζ͕ View ͷେ͖͞ͷݶք஋ʹͳΔ ▸ FLAG_LAYOUT_NO_LIMITS ▸ ը໘αΠζΛ௒͑ͯ View ͷେ͖͞ΛઃఆͰ͖Δ ▸ ࠨ্Λݪ఺ͱͯ͠ɺϚΠφεํ޲ʹ΋ View Λ഑ஔͰ͖Δ 29
  30. Building my own debugging tool on overlay ϐΫηϧϑΥʔϚοτ ▸ ඳը͢Δ

    View ͷϐΫηϧ͕΋ͭΞϧϑΝ஋ ▸ android.graphics.PixelFormat ▸ OPAQUE: ΞϧϑΝ஋ͳ͠ɾෆಁ໌ ▸ TRANSLUCENT: ෳ਺ϏοτͰΞϧϑΝ஋Λදݱ ▸ TRANSPARENT: ࠷௿1ϏοτͰΞϧϑΝ஋Λදݱ 30
  31. Building my own debugging tool on overlay View ͷ௥Ճίʔυ public

    class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onCreate(Bundle icicle) { // …… WindowManager.LayoutParams p = new WM.LP( WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG, FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT ); mWindowManager.addView(mOverlayView, p); } } 31
  32. Building my own debugging tool on overlay View ͷ௥Ճίʔυ public

    class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onCreate(Bundle icicle) { // …… WindowManager.LayoutParams p = new WM.LP( WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG, FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT ); mWindowManager.addView(mOverlayView, p); } } 32
  33. Building my own debugging tool on overlay View ͷ௥Ճίʔυ public

    class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onCreate(Bundle icicle) { // …… WindowManager.LayoutParams p = new WM.LP( WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG, FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT ); mWindowManager.addView(mOverlayView, p); } } 33
  34. Building my own debugging tool on overlay View ͷ௥Ճίʔυ public

    class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onCreate(Bundle icicle) { // …… WindowManager.LayoutParams p = new WM.LP( WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG, FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT ); mWindowManager.addView(mOverlayView, p); } } 34
  35. Building my own debugging tool on overlay View ͷ௥Ճίʔυ public

    class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onCreate(Bundle icicle) { // …… WindowManager.LayoutParams p = new WM.LP( WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG, FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT ); mWindowManager.addView(mOverlayView, p); } } 35
  36. Building my own debugging tool on overlay View ͷ௥Ճίʔυ public

    class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onCreate(Bundle icicle) { // …… WindowManager.LayoutParams p = new WM.LP( WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG, FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT ); mWindowManager.addView(mOverlayView, p); } } 36
  37. Building my own debugging tool on overlay View ͷ࡟আίʔυ public

    class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onDestroy() { // …… mWindowManager.removeView(mOverlayView); } } 37
  38. Building my own debugging tool on overlay View ͷ࡟আίʔυ public

    class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onDestroy() { // …… mWindowManager.removeView(mOverlayView); } } 38
  39. Building my own debugging tool on overlay ඳը͢Δ View ͷ؅ཧ

    ▸ WindowManager ͸ View ͷ௥Ճɾ࡟আɾߋ৽͔͠͠ͳ͍ ▸ ͲͷλΠϛϯάͰ௥Ճɾ࡟আɾߋ৽͢Δ͔͸ࣗ෼Ͱ؅ཧ ▸ WindowManager ʹ findViewById ͷΑ͏ͳ΋ͷ͸ͳ͍ ▸ View ͷΠϯελϯεΛϝϯόʔʹ͓͔࣋ͬͯͳ͍ͱ࡟আ Ͱ͖ͳ͘ͳΔ ▸ View ͷϓϩύςΟΛมߋ͢ΔͨΊʹ΋ඞཁ 39
  40. Building my own debugging tool on overlay શͯ͸ View Ͱ͋Δ

    40 View http://slides.com/robwormald/everything-is-a-stream#/
  41. Building my own debugging tool on overlay ଞͷΞϓϦʹ΋ View ΛॏͶ͍ͨʁ

    ▸ Activity Ͱ؅ཧ͢Δ৔߹͸ࣗ෼ͷΞϓϦʹ͔͠ॏͳΒͳ͍ ▸ ϥΠϑαΠΫϧΛ௒͑ͨ View ͷ؅ཧΛ͢Δඞཁੑ ▸ View ࣗମ͸ Activity ͱ͸ಠཱ͍ͯ͠Δ ▸ ϥΠϑαΠΫϧΛ௒͑ΒΕΔ View ͷ؅ཧํ๏ʁ ▸ Service 41
  42. Building my own debugging tool on overlay ଞͷΞϓϦʹ΋ View ΛॏͶ͍ͨʁ

    ▸ Activity Ͱ؅ཧ͢Δ৔߹͸ࣗ෼ͷΞϓϦʹ͔͠ॏͳΒͳ͍ ▸ ϥΠϑαΠΫϧΛ௒͑ͨ View ͷ؅ཧΛ͢Δඞཁੑ ▸ View ࣗମ͸ Activity ͱ͸ಠཱ͍ͯ͠Δ ▸ ϥΠϑαΠΫϧΛ௒͑ΒΕΔ View ͷ؅ཧํ๏ʁ ▸ Service 42
  43. ཪͰ VIEW Λ ߋ৽͠ଓ͚Δ

  44. Building my own debugging tool on overlay όοΫάϥϯυͰ View Λදࣔ͠ଓ͚Δʹ͸

    ✓ View ͸ Service Ͱ΋ੜ੒Ͱ͖Δ ▸ Service ͸ϝΠϯεϨουͰಈ࡞͢Δ ✓ Activity ͱ͸͜ͱͳΔϥΠϑαΠΫϧͰಈ͔͢ ▸ όοΫάϥ΢ϯυͰৗʹಈ͖ଓ͚ΒΕΔ ➡ Service Ͱ View Λ WindowManager ʹ౉ͤ͹ɺ
 ଞͷΞϓϦʹॏͶͯදࣔ͠ଓ͚ΒΕΔ 44
  45. Building my own debugging tool on overlay Service Ͱ View

    Λඳը͢Δͱ͖ͷઃܭ ▸ ඳը͢Δ View ͷϥΠϑαΠΫϧ؅ཧ ▸ Activity ͕ͯ͘͠ΕΔ͜ͱΛ Service Ͱ࠶࣮૷͢Δ ๏ ϥΠϑαΠΫϧͷ։࢝: Service#onCreate ͳͲ ๏ ϥΠϑαΠΫϧͷऴྃ: Service#onDestroy ๏ ConfigurationChange: BroadcastReceiver 45
  46. Building my own debugging tool on overlay Sort of …

    <manifest package=“”> <application> <activity android:name=“.MyActivity” android:configChanges=“keyboard| keyboardHidden|screenLayout|screenSize| orientation|density|fontScale|layoutDirection| locale|mcc|mnc|navigation|smallestScreenSize| touchScreen|uiMode”/> </application> </manifest> 46
  47. Building my own debugging tool on overlay Sort of …

    <manifest package=“”> <application> <activity android:name=“.MyActivity” android:configChanges=“keyboard| keyboardHidden|screenLayout|screenSize| orientation|density|fontScale|layoutDirection| locale|mcc|mnc|navigation|smallestScreenSize| touchScreen|uiMode”/> </application> </manifest> 47
  48. Building my own debugging tool on overlay Service Ͱ View

    Λඳը͢Δͱ͖ͷઃܭ ▸ DroidKaigi ΞϓϦͰͷ࣮૷ ▸ OverlayViewManager ▸ Service ಺Ͱͷ View ͷϥΠϑαΠΫϧΛѲ͍ͬͯΔ ▸ ը໘ભҠ౳͸ߟྀ͍ͯ͠ͳ͍ ▸ ը໘ભҠ౳ΛؚΊͨ View ϕʔεͷը໘ߏஙϑϨʔϜϫʔΫ ▸ e.g. square/flow and square/mortar 48
  49. Building my own debugging tool on overlay Service Ͱ View

    Λඳը͢Δͱ͖ͷઃܭ 49 OverlayViewManager create destroy configChanges WindowManager Service onCreate addView onDestroy removeView configChanges updateViewLayout
  50. Building my own debugging tool on overlay OverlayViewManger Ͱ͢Δ͜ͱ ▸

    OverlayViewManger#create ▸ WindowManager#addView ΛݺͿ ▸ OverlayViewManger#changeConfiguration ▸ WindowManager#updateViewLayout ΛݺͿ ▸ OverlayViewManger#destroy ▸ WindowManager#removeView ΛݺͿ 50
  51. Building my own debugging tool on overlay OverlayViewManager ͷ࣮૷ public

    class OverlayViewManager { private final Context mContext; // Service private final WindowManager mWindowManager; private final WindowManager.LayoutParams mParams; private View mRootView; public void create() { mRootView = LayoutInflater.from(mContext).inflate( R.layout.view_root_overlay, null, false); mWindowManager.addView(mRootView, mParams) } } 51
  52. Building my own debugging tool on overlay OverlayViewManager ͷ࣮૷ public

    class OverlayViewManager { private final Context mContext; // Service private final WindowManager mWindowManager; private final WindowManager.LayoutParams mParams; private View mRootView; public void destroy() { if (mRootView == null) return; mWindowManager.removeView(mRootView) } } 52
  53. Building my own debugging tool on overlay Service Ͱ ConfigurationChange

    Λѻ͏ ▸ BroadcastReceiver Ͱ ConfigurationChange Λݕ஌ ▸ BroadcastReceiver#onReceive Ͱ View Λ࠶ඳը ▸ ref. WindowManager#updateViewLayout 53
  54. Building my own debugging tool on overlay Service Ͱ ConfigurationChange

    Λѻ͏ public class OverlayViewService extends Service { private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context c, Intent i) { mOverlayViewManager.changeConfiguration(); } } } 54
  55. Building my own debugging tool on overlay Service Ͱ ConfigurationChange

    Λѻ͏ public class OverlayViewService extends Service { private final BroadcastReceiver mReceiver = //… @Override public void onCreate() { //…… IntentFilter filter = new IntentFilter( Intent.ACTION_CONFIGURATION_CHANGE); registerReceiver(mReceiver, filter); } } 55
  56. Building my own debugging tool on overlay Service Ͱ ConfigurationChange

    Λѻ͏ public class OverlayViewService extends Service { private final BroadcastReceiver mReceiver = //… @Override public void onCreate() { //…… IntentFilter filter = new IntentFilter( Intent.ACTION_CONFIGURATION_CHANGE); registerReceiver(mReceiver, filter); } } 56
  57. Building my own debugging tool on overlay Service Ͱ ConfigurationChange

    Λѻ͏ public class OverlayViewService extends Service { private final BroadcastReceiver mReceiver = //… @Override public void onDestroy() { //…… unregisterReceiver(mReceiver); } } 57
  58. Building my own debugging tool on overlay LayoutInflater.from(Context) ͷҾ਺ ▸

    Context ͔Β LayoutInflater ΛऔΓग़͢ ▸ LayoutInflater ͔Βੜ੒͞ΕΔ Veiw ͸ৗʹಉ͡Ͱ͸ͳ͍ ▸ Context ʹΑͬͯৼΔ෣͍͕͕ͪ͏ ▸ ద੾ͳ Context Λ࢖Θͳ͍ͱݟͨ໨͕มΘͬͯ͠·͏ 58
  59. Building my own debugging tool on overlay Activity ͱ Service

    ͷҧ͍ ▸ Activity ▸ ContextThemeWrapper ͷࢠΫϥε ▸ ςʔϚͰઃఆͨ͠ଐੑ஋Λ͍࣋ͬͯΔ ▸ Service ▸ ContextWrapper ͷࢠΫϥε ▸ ςʔϚ͸ଘࡏ͠ͳ͍ 59
  60. Building my own debugging tool on overlay Context ͷϥοϓ ▸

    Service Λ ContextThemeWrapper Ͱϥοϓ͠Α͏ ▸ Composite ύλʔϯ ▸ ϥοϓͨ͠ Context Λ࢖͑͹ Service ಺Ͱ΋ςʔϚ͕ద༻ Ͱ͖Δ 60
  61. Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷

    public class OverlayViewManager { private final Context mContext; // Service private Context mThemedContext; private View mRootView; public void create() { mThemedContext = new OverlayViewContext(mContext); mRootView = LayoutInflater.from(mThemedContext).inflate( R.layout.view_root_overlay, null, false); } } 61
  62. Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷

    public class OverlayViewManager { private final Context mContext; // Service private Context mThemedContext; private View mRootView; public void create() { mThemedContext = new OverlayViewContext(mContext); mRootView = LayoutInflater.from(mThemedContext).inflate( R.layout.view_root_overlay, null, false); } } 62
  63. Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷

    /* package */ class OverlayViewContext extends ContextThemeWrapper { public OverlayViewContext(Context base) { super(context, R.style.AppTheme); } } 63
  64. Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷

    /* package */ class OverlayViewContext extends ContextThemeWrapper { public OverlayViewContext(Context base) { super(context, R.style.AppTheme); } } 64
  65. Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷

    /* package */ class OverlayViewContext extends ContextThemeWrapper { private LayoutInflater mInflater; @Override public Object getSystemServcie(String name) { // …… } } 65
  66. Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷

    private LayoutInflater mInflater; @Override public Object getSystemServcie(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from( getBaseContext()).cloneInContext(this); } return mInflater; } return super.getSystemService(name); } 66
  67. Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷

    private LayoutInflater mInflater; @Override public Object getSystemServcie(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from( getBaseContext()).cloneInContext(this); } return mInflater; } return super.getSystemService(name); } 67
  68. Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷

    private LayoutInflater mInflater; @Override public Object getSystemServcie(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from( getBaseContext()).cloneInContext(this); } return mInflater; } return super.getSystemService(name); } 68
  69. Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷

    private LayoutInflater mInflater; @Override public Object getSystemServcie(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from( getBaseContext()).cloneInContext(this); } return mInflater; } return super.getSystemService(name); } 69
  70. Building my own debugging tool on overlay Service ͷऴྃͱϓϩηεͷऴྃ ▸

    Service ͕ಈ͖ଓ͚ΔݶΓϓϩηε͸ੜ͖͍ͯΔ ▸ Service ΛࢭΊΔํ๏ ▸ Context#stopService(Intent) ▸ Service#stopSelf() ▸ ϓϩηεΛࢭΊΔͨΊʹϢʔβ͕औΔߦಈ ▸ λεΫϦετ͔ΒΞϓϦΛফ͢ 70
  71. Building my own debugging tool on overlay Service ͷऴྃͱϓϩηεͷऴྃ ▸

    λεΫϦετ͔ΒΞϓϦΛऴྃ ▸ Service#onTaskRemoved ▸ ͜͜Ͱ Service ΛࢭΊͳ͍ͱϓϩ ηε͸ੜ͖ଓ͚ͯ͠·͏ ▸ ͳΜ͔ແݶʹੜ͖͍ͯΔΞϓϦ ͕͍Δ => ˑ1 71
  72. Building my own debugging tool on overlay Service ͷऴྃͱϓϩηεͷऴྃ ▸

    γεςϜ͕ڧ੍తʹϓϩηεΛऴྃ͢Δ৔߹΋͋Δ ▸ ද͍ࣔͯͨ͠ View ͕ٸʹ͍ͳ͘ͳΔ ▸ ϢʔβͷΠϯλϥΫγϣϯ͕͋Δͱ͖͸க໋త… ▸ ग़དྷΔݶΓϓϩηεΛ௕ੜ͖͍ͤͨ͞ 72
  73. Building my own debugging tool on overlay Service ͷऴྃͱϓϩηεͷऴྃ ▸

    γεςϜ͕ڧ੍తʹϓϩηεΛऴྃ͢Δ৔߹΋͋Δ ▸ ද͍ࣔͯͨ͠ View ͕ٸʹ͍ͳ͘ͳΔ ▸ ϢʔβͷΠϯλϥΫγϣϯ͕͋Δͱ͖͸க໋త… ▸ ग़དྷΔݶΓϓϩηεΛ௕ੜ͖͍ͤͨ͞ 73
  74. ϓϩηεΛ ಈ͔͠ଓ͚Δ

  75. Building my own debugging tool on overlay Android ʹ͓͚Δϓϩηεͷ༏ઌ౓ ▸

    4 छྨͷ༏ઌ౓ ▸ Foreground Process ▸ Visible Process ▸ Service Process ▸ Cached Process ▸ Լͷ΋ͷ΄Ͳ༏ઌ౓΋௿͍ͷͰɺkill ͷର৅ʹͳΔ 75
  76. Building my own debugging tool on overlay Android ʹ͓͚Δϓϩηεͷ༏ઌ౓ ▸

    Service ͕ؔ܎͢Δϓϩηεͷ༏ઌ౓ ▸ Visible Process ▸ Service Process ▸ ͳΜͱ͔ Visible Process ʹঢ֨͢Ε͹௕ੜ͖Ͱ͖Δ 76
  77. Building my own debugging tool on overlay Android ʹ͓͚Δϓϩηεͷ༏ઌ౓ ▸

    Service ͕ؔ܎͢Δϓϩηεͷ༏ઌ౓ ▸ Visible Process ▸ Service Process ▸ ͳΜͱ͔ Visible Process ʹঢ֨͢Ε͹௕ੜ͖Ͱ͖Δ 77
  78. Building my own debugging tool on overlay Service Process ▸

    Service#startService Ͱৗற͢Δ Service Λ΋ͭϓϩηε ▸ ϝϞϦ͕ṧഭͯ͘͠Δͱ kill ͞ΕΔ ▸ ௕ੜ͖͍ͯ͠Δϓϩηε͸ kill ͷର৅ʹͳΔ ▸ ΋͠ϝϞϦϦʔΫ౳Ͱ Service ͕ਖ਼ৗऴྃͰ͖͍ͯͳ͍ ৔߹ʹϝϞϦΛઐ༗͠ଓ͚ͯ͠·͏ͨΊ 78
  79. Building my own debugging tool on overlay Android ʹ͓͚Δϓϩηεͷ༏ઌ౓ ▸

    Service ͕ؔ܎͢Δϓϩηεͷ༏ઌ౓ ▸ Visible Process ▸ Service Process ▸ ͳΜͱ͔ Visible Process ʹঢ֨͢Ε͹௕ੜ͖Ͱ͖Δ 79
  80. Building my own debugging tool on overlay Visible Process ▸

    Ϣʔβʹͱͬͯॏཁͳ৘ใΛද͍ࣔͯ͠Δϓϩηε ▸ e.g. μΠΞϩάͷཪʹ͍Δ Activity Λ͍࣋ͬͯΔ ▸ e.g. Service#startForeground Ͱ௨஌Λग़͍ͯ͠Δ ▸ WindowManager ʹ View Λग़͍ͯͯ͠΋௚઀͸ Visible Process ʹͳΒͳ͍ 80
  81. Building my own debugging tool on overlay Visible Process ▸

    Ϣʔβʹͱͬͯॏཁͳ৘ใΛද͍ࣔͯ͠Δϓϩηε ▸ e.g. μΠΞϩάͷཪʹ͍Δ Activity Λ͍࣋ͬͯΔ ▸ e.g. Service#startForeground Ͱ௨஌Λग़͍ͯ͠Δ ▸ WindowManager ʹ View Λग़͍ͯͯ͠΋௚઀͸ Visible Process ʹͳΒͳ͍ 81
  82. Building my own debugging tool on overlay ϝϞϦʹ༏͍͠ Service ▸

    Visible Service Ͱ΋ϝϞϦ͕ݫ͍͠ͱ kill ͞ΕΔ ▸ ϝϞϦʹ༏͍͠ Service Λ࡞Ζ͏ ▸ ϝϞϦϦʔΫ͸͝๏౓ ▸ Service ʹ΋ϥΠϑαΠΫϧ͕͋Δ͜ͱʹ஫ҙ͢Δ ▸ ը໘ભҠΛ࡞Δ৔߹ɺ౎౓ඞཁͳ͍ View Λ remove ͢Δ 82
  83. Building my own debugging tool on overlay ॏͶͨ View ʹ৘ใΛදࣔ͢Δ

    ▸ ߏஙͨ͠ View ʹσʔλΛ౉͍ͨ͠ ▸ σόοά༻ͷ৘ใΛग़͢ ▸ ΞϓϦͷ͍Ζ͍Ζͳ෦෼͔Βσʔ λΛ౉ͤΔઃܭ͕ඞཁ 83
  84. Building my own debugging tool on overlay ॏͶͨ View ʹ৘ใΛදࣔ͢Δ

    ▸ ߏஙͨ͠ View ʹσʔλΛ౉͍ͨ͠ ▸ σόοά༻ͷ৘ใΛग़͢ ▸ ΞϓϦͷ͍Ζ͍Ζͳ෦෼͔Βσʔ λΛ౉ͤΔઃܭ͕ඞཁ 84
  85. Activity ͳͲ ͱͭͳ͗͜Ή

  86. Building my own debugging tool on overlay Service ʹͭͳ͗͜Ή 3

    ͭͷํ๏ ▸ Service ʹσʔλΛΘͨ͢ 3ͭͷํ๏ ▸ startService ͷ Intent ʹσʔλΛͭΊΔ ▸ EventBus Λ׆༻ͯ͠σʔλΛΘͨ͢ ▸ Dagger ౳ͷ DI ͰείʔϓΛ੾Δ & Rx Λ࢖͏ 86
  87. Building my own debugging tool on overlay startService ͷ Intent

    ʹσʔλΛͭΊΔ ▸ Intent#putExtra() Λ׆༻ ▸ Service#onStartCommand() Ͱड͚औΔ ▸ pros & cons ▸ Android ϑϨʔϜϫʔΫͷ࢓૊ΈͰ׬݁͢Δ ▸ σʔλܕʹ Parcelable ͷ࣮૷͕ඞཁ ▸ View Λ؅ཧ͢Δந৅ϨΠϠʹ۩ମతͳॲཧ͕ೖΓࠐΉ 87
  88. Building my own debugging tool on overlay startService ͷ Intent

    ʹσʔλΛͭΊΔ public class DebugOverlayService extends Service { public static final String EXTRA_DATA = // …… private OverlayViewManager mManager; @Override public int onStartCommand(Intent i, int flags, int startId) { // …… Data data = i.getParcelableExtra(EXTRA_DATA); mManager.onReceiveData(data); } } 88
  89. Building my own debugging tool on overlay startService ͷ Intent

    ʹσʔλΛͭΊΔ public class DebugOverlayService extends Service { public static final String EXTRA_DATA = // …… private OverlayViewManager mManager; @Override public int onStartCommand(Intent i, int flags, int startId) { // …… Data data = i.getParcelableExtra(EXTRA_DATA); mManager.onReceiveData(data); } } 89
  90. Building my own debugging tool on overlay startService ͷ Intent

    ʹσʔλΛͭΊΔ public class DebugOverlayService extends Service { public static final String EXTRA_DATA = // …… private OverlayViewManager mManager; @Override public int onStartCommand(Intent i, int flags, int startId) { // …… Data data = i.getParcelableExtra(EXTRA_DATA); mManager.onReceiveData(data); } } 90
  91. Building my own debugging tool on overlay EventBus Λ׆༻ͯ͠σʔλΛΘͨ͢ ▸

    greenrobot/EventBus, square/otto, reactivex/RxJava ͳͲ ▸ γϯϓϧͳ publisher/subscriber ύλʔϯ ▸ pros & cons ▸ ࢖͍ํΛ֮͑Ε͹؆୯ʹద༻Ͱ͖Δ ▸ Parcelable ͷ࣮૷͕͍Βͳ͍ ▸ ϥΠϒϥϦʹΑͬͯ͸ Deprecated ʹͳ͍ͬͯΔ 91
  92. Building my own debugging tool on overlay EventBus Λ׆༻ͯ͠σʔλΛΘͨ͢ public

    class DebugOverlayView extends RelativeLayout { private EventBus; @Subscribe public void onDataReceived(Data data) { // draw something from data } } 92
  93. Building my own debugging tool on overlay EventBus Λ׆༻ͯ͠σʔλΛΘͨ͢ public

    class DebugOverlayView extends RelativeLayout { private EventBus; @Subscribe public void onDataReceived(Data data) { // draw something from data } } 93
  94. Building my own debugging tool on overlay Dagger ౳ͷ DI

    ͰείʔϓΛ੾Δ & Rx Λ࢖͏ ▸ είʔϓͷ੾Γํ ▸ Application ͷϥΠϑαΠΫϧʹ߹ΘͤΔείʔϓ ▸ Activity ͷϥΠϑαΠΫϧʹ߹ΘͤΔείʔϓ ▸ Service ͷϥΠϑαΠΫϧʹ߹ΘͤΔείʔϓ ▸ DroidKaigi ΞϓϦ ▸ Application ͷείʔϓʹ͍Δ΋ͷ͕ϧʔςΟϯάΛ୲౰ 94
  95. ςΩετ Dagger ౳ͷ DI ͰείʔϓΛ੾Δ & Rx Λ࢖͏ 95 ApplicationScope

    LogEmitter ActivityScope ServiceScope listen send
  96. Building my own debugging tool on overlay Dagger ౳ͷ DI

    ͰείʔϓΛ੾Δ & Rx Λ࢖͏ ▸ pros & cons ▸ ΦϒδΣΫτͷϥΠϑαΠΫϧ͕໌֬ʹͳΔ ▸ EventBus ʹྨࣅͷύλʔϯ͕ Rx Ͱ׬݁͢Δ ▸ ࣗ෼Ͱ EventBus ͷ࢓૊ΈΛ࡞Δඞཁ͕͋Δ 96
  97. ·ͱΊ

  98. Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ

    ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 98
  99. Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ

    ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 99
  100. Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ

    ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 100
  101. Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ

    ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 101
  102. Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ

    ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 102
  103. Building my own debugging tool on overlay ͍͞͝ʹ ▸ ͜ͷτʔΫʹ͸एׯͷࠇຐज़త಺༰ؚ͕·Ε͍ͯ·͢

    ▸ Ԡ༻͢Δ৔߹ɺ༻๏༻ྔΛकָ͓ͬͯ͘͠࢖͍͍ͩ͘͞ 103
  104. BUILDING MY OWN DEBUGGING TOOL ON OVERLAY Keishin Yokomaku /

    DroidKaigi 2017 Day 2 - Room 2
  105. Building my own debugging tool on overlay Appendix ▸ ࢀߟࢿྉ

    ▸ WindowManager - Android Developers ▸ WindowManager.LayoutParams - Android Developers ▸ Whoa, Views can do that?
 WindowManager ideas and tricks! - @eric_cochran ▸ DroidKaigi/conference-app-2017 - GitHub 105
  106. Drivemode We are hiring! 106

  107. Drivemode What we do 107