Build my own debugging tool on overlay

Build my own debugging tool on overlay

Bbe9718bebdafbdc8dabbe3cadf1bc46?s=128

Keishin Yokomaku

March 10, 2017
Tweet

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