Day1 Keynote in DroidKaigi 2016

Day1 Keynote in DroidKaigi 2016

Day1 Keynote in DroidKaigi 2016

6dd0483f1353a4a359e92633cfd65c64?s=128

Daichi Furiya (Wasabeef)

February 17, 2016
Tweet

Transcript

  1. OSSの動向を捉えた実装方針 wasabeef DroidKaigi 2016

  2. About me Daichi Furiya wasabeef @wasabeef_jp CyberAgent, Inc.

  3. OSSの動向を捉えた実装方針?

  4. Research

  5. GitHub/trending Android Weekly Android Arsenal Twitter Research

  6. Introduction

  7. Languages

  8. Kotlin Java • RetroLambda • Lightweight-Stream-API • ThreeTen Android Languages

  9. Kotlin by JetBrains

  10. Kotlin 1.0 Java連携 …more Kotlin

  11. RetroLambda by Esko Luontola

  12. Lambda Method Reference RetroLambda view.setOnClickListener(v -> { finish(); }); view.setOnClickListener(this::something);

  13. Lightweight-Stream-API by Victor Melnik

  14. Stream API Lightweight-Stream-API Stream.of(lines) .map(str -> str.split(t)) .filter(arr -> arr.length

    == 2) .map(arr -> new Word(arr[0], arr[1])) .collect(Collectors.toList());
  15. Optional Lightweight-Stream-API Optional.ofNullable(getSupportActionBar()) .ifPresent(ab -> { ab.setDisplayHomeAsUpEnabled(true); ab.setHomeButtonEnabled(true); }); Optional.ofNullable(i.getStringExtra(EXTRA_URI))

    .map(Uri::parse) .orElse(null);
  16. ThreeTen Android by Jake Wharton

  17. JSR-310 ThreeTen Android // Now LocalDateTime.now(); // 2016.2.18 10:30:40 LocalDateTime.of(2016,

    2, 18, 10, 30, 40); // +1 truncated second LocalDateTime.now() .plusHours(1).truncatedTo(ChronoUnit.HOURS); // Epoch LocalDateTime.now() .toInstant(ZoneOffset.UTC).toEpochMilli();
  18. Views

  19. Support Library Android-ObservableScrollView Calligraphy florent37/ViewAnimator View

  20. Support Library by Google

  21. View (RecyclerView...etc ) RenderScript MultiDex Annotations Support Library

  22. Sample... Support Library compile 'com.android.support:support-v4:+' compile 'com.android.support:appcompat-v7:+' compile 'com.android.support:design:+' compile

    'com.android.support:recyclerview-v7:+' compile 'com.android.support:cardview-v7:+' compile 'com.android.support:support-annotations:+' compile ‘com.android.support:percent:+'
  23. Android ObservableScrollView by ksoichiro

  24. ScrollView , ListView, RecyclerViewなどのスクロー ル制御を監視 Android-ObservableScrollView https://github.com/ksoichiro/Android-ObservableScrollView

  25. Calligraphy by Christopher Jenkins

  26. Calligraphy アプリ全体にFont適用 xmlでもjavaでも可 簡単 https://github.com/chrisjenx/Calligraphy

  27. CalligraphyConfig Calligraphy CalligraphyConfig.initDefault(new CalligraphyConfig.Builder() .setDefaultFontPath("fonts/mplus-2p-regular.ttf") .setFontAttrId(R.attr.fontPath) .build();

  28. ViewAnimator by Florent CHAMPIGNY

  29. ViewAnimator AnimatorSet animSet = new AnimatorSet(); animSet.playTogether( ObjectAnimator.ofFloat(image, View.TRANSLATION_Y, -1000,0),

    ObjectAnimator.ofFloat(image, View.ALPHA, 0,1), ObjectAnimator.ofFloat(text, View.TRANSLATION_X, -200,0) ); animSet.setInterpolator(new DescelerateInterpolator()); animSet.setDuration(2000); animSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { AnimatorSet anim = new AnimatorSet(); anim.playTogether( ObjectAnimator.ofFloat(image, View.SCALE_X, 1f, 0.5f, 1f), ObjectAnimator.ofFloat(image, View.SCALE_Y, 1f, 0.5f, 1f) ); anim.setInterpolator(new AccelerateInterpolator()); anim.setDuration(1000); anim.start(); } }); animSet.start();
  30. ViewAnimator ViewAnimator .animate(image) .translationY(-1000, 0) .alpha(0, 1) .andAnimate(text) .dp().translationX(-200, 0)

    .descelerate() .duration(2000) .thenAnimate(image) .scale(1f, 0.5f, 1f) .accelerate() .duration(1000) .start();
  31. DataBinding

  32. Android Data Binding by Google

  33. xmlとjavaのBinding Annotation Processing たまにビルドエラーが出る.. Android Data Binding

  34. Android Data Binding <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id=“@+id/user_name“

    android:layout_width="wrap_content" android:layout_height="wrap_content"/> <ImageView android:id=“@+id/user_thumbnail“ android:layout_width="160dp" android:layout_height="120dp"/> </LinearLayout>
  35. Android Data Binding <layout xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView

    android:id=“@+id/user_name“ android:layout_width="wrap_content" android:layout_height="wrap_content"/> <ImageView android:id=“@+id/user_thumbnail“ android:layout_width="160dp" android:layout_height="120dp"/> </LinearLayout> </layout>
  36. Android Data Binding <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data name="MainBinding"> <variable name="user" type="com.example.User"/>

    </data> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id=“@+id/user_name“ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.name}" android:textColor="@{user.isWomen? @color/pink : @color:blue}"/> <ImageView android:id=“@+id/user_thumbnail“ android:layout_width="160dp" android:layout_height="120dp" bind:imageUrl="@{user.thumbnail}"/> </LinearLayout> </layout>
  37. Custom Setters Android Data Binding public final class ImageBindingAdapters {

    @BindingAdapter({ "bind:image" }) public static void loadImage(ImageView view, String url) { Glide.with(view.getContext().getApplicationContext()) .load(url) .into(view); } } <ImageView android:layout_width="160dp" android:layout_height="120dp" bind:imageUrl="@{user.thumbnail}"/>
  38. DataBindingUtil Android Data Binding @Override protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState); MainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); binding.userName.setOnClickListener(v -> ...); } <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data name="MainBinding"> <variable name="user" type="com.example.User"/> </data> <!-- ... -- </layout>
  39. Networking

  40. (Volley) Retrofit + OkHttp Networking

  41. Retrofit+OkHttp by Square

  42. REST RxJava support Pluggable client Converters(Gson, Wire...) Retrofit+OkHttp

  43. Retrofit Retrofit retrofit = new Retrofit.Builder() .client(okHttpClient) .baseUrl("https://api.github.com") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create())

    .build(); GitHubService service = retrofit.create(GitHubService.class); service.repos("wasabeef") .subscribe(repo -> { // ... }, e -> { Timber.w(e); }); public interface GitHubService { @GET(/users/{user}/repos) Observable<List<Repo>> repos(@Path(user) String user); }
  44. JSON & ProtoBuf

  45. (Gson) (Jackson) (Moshi) Wire Serialisations

  46. Wire by Square

  47. Protocol Buffers okioを利用 Server/Clientで定義を共通化 Webからは扱いづらい Wire

  48. Wire syntax = "proto3"; package helloworld; message HelloRequest { string

    name = 1; } message HelloReply { string message = 1; } hello.proto
  49. Wire Build # java -jar wire-compiler-2.0.1-jar-with-dependencies.jar \ —proto_path=. \ —java_out=.

    hello.proto Writing helloworld.HelloRequest to . Writing helloworld.HelloReply to .
  50. Parcelables

  51. (android-parcelable-intellij-plugin) Parceler (Auto-Value-Parcel) Icepick Parcelables

  52. Parceler by John Ericksen

  53. Annotation Processing AutoValue Parceler

  54. Parceler @Parcel public class User { public String name; public

    String thumbnail; User() { } } // Wrap Bundle bundle = new Bundle(); bundle.putParcelable("user", Parcels.wrap(user)); // Unwrap User user = Parcels.unwrap(getIntent().getParcelableExtra("user"));
  55. Icepick by Frankie Sardo

  56. Simple Icepick public class MainActivity extends Activity { @State String

    name; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Icepick.restoreInstanceState(this, savedInstanceState); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Icepick.saveInstanceState(this, outState); } }
  57. Image Loaders

  58. (Universal Image Loader) Picasso Glide Fresco Image Loaders

  59. Picasso by Square

  60. Simple Cache Transformations Debug Picasso

  61. Simple Picasso Picasso.with(context) .load(“http://i.imgur.com/DvpvklR.png”) .setIndicatorsEnabled(true) .into(imageView);

  62. Glide by Google (unofficial)

  63. Glide Bitmap Pool Gif support Thumbnail Animation support Transformations

  64. Simple Glide Glide.with(context) .load(“http://i.imgur.com/DvpvklR.png”) .crossFade() .thumbnail(.1f) .into(imageView);

  65. Picasso? Glide?

  66. Picasso? Glide? http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en

  67. Picasso? Glide? http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en

  68. Picasso? Glide? http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en Library's size

  69. Picasso? Glide? http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en Method Count

  70. Fresco by Facebook

  71. Fresco Ashmem heap View Gif support Animation

  72. Fresco

  73. Fresco <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/my_image_view" android:layout_width="20dp" android:layout_height="20dp" fresco:fadeDuration="300" fresco:actualImageScaleType="focusCrop" fresco:placeholderImage="@color/wait_color" fresco:placeholderImageScaleType="fitCenter" fresco:failureImage="@drawable/error"

    fresco:failureImageScaleType="centerInside" fresco:retryImage="@drawable/retrying" fresco:retryImageScaleType="centerCrop" fresco:progressBarImage="@drawable/progress_bar" fresco:progressBarImageScaleType="centerInside" fresco:progressBarAutoRotateInterval="1000" fresco:backgroundImage="@color/blue" fresco:overlayImage="@drawable/watermark" fresco:pressedStateOverlayImage="@color/red" fresco:roundAsCircle="false" fresco:roundedCornerRadius="1dp" fresco:roundTopLeft="true" fresco:roundTopRight="false" fresco:roundBottomLeft="false" fresco:roundBottomRight="true" fresco:roundWithOverlayColor="@color/corner_color" fresco:roundingBorderWidth="2dp" fresco:roundingBorderColor="@color/border_color" />
  74. Effects

  75. Blurry Android StackBlur GPUImage for Android Picasso/Glide Transformations Effects

  76. Blurry by Wasabeef

  77. Blurry Blur RenderScript DownSampling

  78. Android StackBlur by Enrique López Mañas

  79. Blur RenderScript NDK Android StackBlur

  80. Android StackBlur https://github.com/kikoso/android-stackblur

  81. Android StackBlur https://github.com/kikoso/android-stackblur

  82. GPUImage for Android by CyberAgent

  83. GPUImage OpenGL ES 70 Filters Tone Curve

  84. Picasso/Glide Transformations by Wasabeef

  85. Transformations Picasso, Glide, Fresco Crop Blur Color Filter GPU Filter

  86. DI

  87. (AndroidAnnotations) (Square/Dagger) Google/Dagger Butter Knife DI

  88. Dagger2 by Google

  89. Annotation Processing テスト・メンテナンス Dagger2

  90. Butter Knife by Jake Wharton

  91. View Injection Butter Knife public class MainActivity extends Activity {

    @Bind(R.id.user_name) TextView userName; @Bind(R.id.user_thumbnail) ImageView thumbnail; @BindString(R.string.title) String title; @BindDrawable(R.drawable.graphic) Drawable graphic; @BindColor(R.color.red) int red; @BindDimen(R.dimen.spacer) float spacer; }
  92. OnClick, OnTextChange, OnFocusChange...etc Butter Knife @OnClick(R.id.user_name) public void click(View view)

    { // ... } @OnClick({ R.id.user_name, R.id.user_thumbnail }) public void click(View door) { // ... }
  93. FRP

  94. RxJava RxAndroid (RxBinding) (RxLifecycle) FRP

  95. RxJava by Netflix

  96. 非同期、リスト操作が簡単 Retrolambdaがあると良い  Leakが怖い Retrofitと併用 RxJava

  97. Sample RxJava Observable.just("Google", "Apple", "MicroSoft") .map(String::toUpperCase) .subscribe(name -> { Timber.d("OnNext

    " + name); }, throwable -> { Timber.d("OnError"); });
  98. Sample RxJava Observable.just("Google", "Apple", "MicroSoft") .map(String::toUpperCase) .subscribe(name -> { Timber.d("OnNext

    " + name); }, throwable -> { Timber.d("OnError"); });
  99. lift compose rxjava-extras (by Dave Moten) RxJava

  100. RxAndroid by RxAndroid authors

  101. Scheduler RxAndroid

  102. Main Thread RxAndroid Observable.just("one", "two", "three", "four", "five") .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread())

    .subscribe(/* an Observer */); final Handler handler = new Handler(); Observable.just("one", "two", "three", "four", "five") .subscribeOn(Schedulers.newThread()) .observeOn(HandlerScheduler.from(handler)) .subscribe(/* an Observer */) Arbitrary Thread
  103. DB/ORM

  104. (ActiveAndroid) Realm (SQLBrite) Android Orma DB/ORM

  105. Realm by Realm

  106. Not SQLite RxJava? Thread間の制約 Realm

  107. Android Orma by gfx

  108. SQLite Annotation Processing RxJava Semi-automatic migration Android Orma

  109. Event Buses

  110. Otto EventBus (RxJava) Event Buses

  111. Otto by Square

  112. Deprecated! Square @Produceが少し便利 Otto

  113. EventBus by greenrobot

  114. EventBus EventBus3 Threading Support Annotation Processing

  115. Debugging

  116. Timber Hugo Debugging Stetho Leak Canary Takt Crashlytics

  117. Timber by Jake Wharton

  118. Logger Timber.Treeを継承して追加する ことで、出力先を自由に変えれる Timber if (BuildConfig.DEBUG) { Timber.plant(new Timber.DebugTree()); }

    else { Timber.plant(new CrashReportingTree()); }
  119. Hugo by Jake Wharton

  120. AnnotationでMethod Callsを Loggingできる Hugo @DebugLog public String getName(String first, String

    last) { return first + " " + last; } V/Example: ⇢ getName(first="Daichi", last="Furiya") V/Example: ⇠ getName [0ms] = “Daichi Furiya"
  121. Stetho by Facebook

  122. Chrome Developer Toolsを利 用して、Network、Dataの状 況の把握 Stetho-Realm (by uPhyca) Stetho

  123. Stetho

  124. Stetho

  125. Stetho

  126. Leak Canary by Square

  127. メモリリークを検出 Leak Canary

  128. Takt by Wasabeef

  129. FPSを表示 Takt

  130. Crashlytics by Twitter

  131. クラッシュの検出 リアルタイム分析 NDKサポート Crashlytics

  132. Crashlytics

  133. Others

  134. Multi-Dex ProGuard Others

  135. MultiDex by Google

  136. メソッド数の65k制限 最近は安定してきた MultiDex

  137. Android Methods Count MultiDex https://plugins.jetbrains.com/plugin/8076

  138. ProGuard by GuardSquare

  139. ソースコードの難読化 未使用なリソースの削除 難しい ProGuard

  140. ProGuard 15M sample-production.apk Total methods count: 99,280 (multidex enabled) 13M

    sample-production-proguard.apk Total methods count: 54,977 Proguard あり Proguard なし
  141. Conclusion

  142. Thank you. twitter.com/wasabeef_jp wasabeef.jp github.com/wasabeef