非同期処理はAsyncTaskLoaderを使ってたけど、だんだんめんどくさくなってきた。。。
非同期処理をいい感じに扱ってくれるライブラリjdeferredと
AndroidでもJava8のラムダ式を使えるようにするライブラリRetrolambda
を使うとシンプルにかけるらしいので、その備忘録
非同期処理のライブラリはAndroid-promiseとかRxAndroidとかあるけど、
jdeferredのほうがよさ気な気がしてるけど違いはよくわかってない笑
環境は以下の通り
- Ubuntu: 15.04 64bit Desktop
- Android Studio: 1.3.2
- Android Build Tool: 22.0.1
Retrolambdaの導入
Java8をインストール
Java8をインストールして環境変数にパスを設定する
$ javac -version
javac 1.8.0_45
build.gradleにRetrolambdaとjdeferredを追加
AndroidがJava8に対応していないため、Gradleでコンパイルをするとエラーになってしまう
それを回避するために、retrolambda用のgradleのプラグイン(gradle-retrolambda)がある
なので、プラグインを使えるようにブロジェクトのbuild.gradleに
classpath 'me.tatarka:gradle-retrolambda:3.2.2'
を追加
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.3.0' classpath 'me.tatarka:gradle-retrolambda:3.2.2' } }
また、アプリケーションモジュールのbuild.gradleに
apply plugin: 'me.tatarka.retrolambda'
を追記してプラグインを有効にし- compileOptionsに
JavaVersion.VERSION_1_8
を追記して、
Java8でコンパイルするようにし、 - dependenciesに
org.jdeferred:jdeferred-android-aar:1.2.4
を追記して、
jdeferredを使えるようにします- apklib版の
jdeferred-android
もあるけど、gradleはaar形式のみ対応
- apklib版の
全体としては以下な感じ
apply plugin: 'com.android.application' apply plugin: 'me.tatarka.retrolambda' android { compileSdkVersion 20 buildToolsVersion '22.0.1' defaultConfig { minSdkVersion 16 targetSdkVersion 20 ・・・ } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { compile project(":app")' compile 'org.jdeferred:jdeferred-android-aar:1.2.4' }
jdeferredを使う
Java上で書くときは以下の感じ。メソッドチェーンでいい感じに書けます
AndroidDeferredManager dm = new AndroidDeferredManager(); dm.when(() -> { return //非同期の処理 }).done(result -> { //非同期処理が成功した時の処理 }).fail(tr -> { //非同期処理が失敗した時の処理 });
ほかにも、非同期処理を連結するthen()
や、成功失敗にかかわらず実行される処理always()
なんてのもあります!
AndroidDeferredManager dm = new AndroidDeferredManager(); dm.when(() -> { return //非同期の処理 その1 }).then(result -> { return //非同期の処理 その2 }).then(result2 -> { return //非同期の処理 その3 }).done(result3 -> { //非同期処理が成功した時の処理 }).fail(throwable -> { //非同期処理が失敗した時の処理 }).always((state, resolved, rejected) -> { //成功失敗に関わらず行う処理 });
なんてスマートなんでしょう!!
以上!!