[Android] RxAndroid と AWS SDK for Android を組み合わせて使う
AWS を Reactive に実装
最近 Android アプリ開発で RxAndroid を良く触っているのですが、RxJava と同様、非常に良く考えられているライブラリだと思います。
RxAndroid は非同期処理やイベントベースの処理などを構成するためのライブラリです。Android アプリ開発界隈では使われるケースが徐々に増えてきている印象です。RxAndroid や RxJava については以下の記事が分かりやすいです。
- Android開発でRxJavaをチームに導入した話 - クックパッド開発者ブログ
- 7つのサンプルプログラムで学ぶRxJavaの挙動 - クックパッド開発者ブログ
- RxAndroidをカジュアルに使ってみるとか - みんからきりまで
この記事では、そんな RxAndroid と AWS for Android を絡めて「Lambda Functionを呼び出す」という処理を実装してみました。
ライブラリのインポート
まず、Android Studio にて新規プロジェクトを作成した状態が前提となりますので、今回の内容を試す場合は新規プロジェクトを作成した状態で読み進めてください。
まずはアプリモジュールの build.gradle
にライブラリを追加します。今回は aws-android-sdk-core と aws-android-sdk-cognito と aws-android-sdk-lambda を使います。
dependencies { compile 'io.reactivex:rxandroid:0.25.0' compile 'com.amazonaws:aws-android-sdk-core:2.2.2' compile 'com.amazonaws:aws-android-sdk-cognito:2.2.2' compile 'com.amazonaws:aws-android-sdk-lambda:2.2.2' }
保存したら、Sync Project を実行しておきましょう。
早速実装する
ということで、早速実装します。モバイルアプリから AWS の API をコールするには Amazon Cognito を利用しましょう。Amazon Cognito の基本的な使いかたは、以前ブログで紹介した内容を参考にしていただければと思います。
Amazon Cognito の Identity Pool の作成を済ませたら、次のように実装していきましょう。今回はシンプルにしたいので Activity のみで実装しています。
package com.example.sampleapp; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.Toast; import com.amazonaws.auth.CognitoCachingCredentialsProvider; import com.amazonaws.mobileconnectors.lambdainvoker.LambdaFunction; import com.amazonaws.mobileconnectors.lambdainvoker.LambdaInvokerFactory; import com.amazonaws.regions.Regions; import rx.Observable; import rx.Observer; import rx.Subscriber; import rx.android.schedulers.AndroidSchedulers; import rx.schedulers.Schedulers; public class MainActivity extends AppCompatActivity { final AppCompatActivity self = this; static final String IDENTITY_POOL_ID = "us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Lambda FunctionのInvokeを非同期で実行 invokeLambdaFunction("Class", "Method") .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<String>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(String s) { // レスポンスをToastで表示 Toast.makeText(self, s, Toast.LENGTH_LONG).show(); } }); } // Lambda FunctionのInvokerの非同期処理 Observable<String> invokeLambdaFunction(final String firstName, final String lastName) { return Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { // Cognito CognitoCachingCredentialsProvider provider = new CognitoCachingCredentialsProvider(self, IDENTITY_POOL_ID, Regions.US_EAST_1); LambdaInvokerFactory factory = new LambdaInvokerFactory(self, Regions.US_EAST_1, provider); // Lambda SampleInvoker invoker = factory.build(SampleInvoker.class); String message = invoker.hello(new NameInfo(firstName, lastName)); // Subscriberに通知 subscriber.onNext(message); subscriber.onCompleted(); } }); } // LambdaのInvoker public interface SampleInvoker { @LambdaFunction String hello(NameInfo nameInfo); } // Lambda Functionに渡すパラメータ public class NameInfo { String firstName; String lastName; public NameInfo(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } } }
上記は Lambda Function を呼び出す処理を実装しています。Lambda Function 自体は以下のブログで作成したものと同じものを使っています。firstName
と lastName
を受けて、あいさつ的なメッセージを返却するだけのシンプルなものです。予め作成しておいてください。
こんなかんじの Lambda Function です。
exports.handler = function(payload, context) { console.log("Received event"); context.succeed("Hello "+ payload.firstName + payload.lastName + ". Your user ID is " + context.identity.cognitoIdentityId + " and your platform is " + context.clientContext.client.platform); };
SampleInvoker
インターフェースでは hello
メソッドを定義していますが、これが Lambda Function の名前そのものです。他の名前で作成した場合は適宜修正してください。
実行してみよう
ここまでできたら完成です。デバッグしてみると、下図のような結果になるはずです。
あ、そういえば AndroidManifest.xml
に以下の記述を忘れずに。
<uses-permission android:name="android.permission.INTERNET" />
まとめ
Android アプリから AWS のサービスを RxAndroid 経由で利用する方法のご紹介でした。AWS サービスの呼び出しは基本的に非同期処理になるので、今回の例のような実装は絶対に必要になってきます。ぜひ参考にしてみてください。