160714 roppongi aar3_how_to_implement_activity

Post on 08-Jan-2017

412 views 0 download

Transcript of 160714 roppongi aar3_how_to_implement_activity

In 2016, how do you implement"Web API client Activity"?

Tsuyoshi Yoshioka (@tsuyogoro)Mercari, Inc.

About meTsuyoshi Yoshioka (@tsuyogoro)

Android engineer

Mercari, Inc

How do you implement this app?

Using a web API - http://zipcloud.ibsnet.co.jp/doc/api

Today’s focus on

How to support “orientation change” ?

Base of my idea

Activity(Portrait)

Activity(Landscape)

DataModelAPI task

Web API(Search address)

share share

“Wait…” dialog

1. How to share “Data model” ?2. How to share “API task” ?3. How to show ProgressDialog in correct period ?

We have 3 weapons

● Databinding

● RxJava

● Lifecycle of Activity & Fragment

1.Sharing model with databinding

public class ZipSearchActivityModel implements Serializable {

private static final long serialVersionUID = 123L;

/** * ユーザの入力した郵便番号 * */ public ObservableField<String> zipCode = new ObservableField<>();

/** * 検索した結果の住所 * (場合によってはエラー文言を表示するのに使う ) * */ public ObservableField<String> address = new ObservableField<>();

}

<EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@={model.zipCode}"/>

<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:layout_marginBottom="16dp" android:text="@{model.address}"/>

☆ Two-way bindinghttps://halfthought.wordpress.com/2016/03/23/2-way-data-binding-on-android/

1.Sharing model with databinding

Can implement model sharing, Quite simple & safely

public class ZipSearchActivityModel implements Serializable {

private static final long serialVersionUID = 123L;

/** * ユーザの入力した郵便番号 * */ public ObservableField<String> zipCode = new ObservableField<>();

/** * 検索した結果の住所 * (場合によってはエラー文言を表示するのに使う ) * */ public ObservableField<String> address = new ObservableField<>();

} Serializable

Serializable

Can use android studio plug-in

@Overrideprotected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putSerializable(BUNDLE_KEY_MODEL, model);}

2. Task sharing with RxJava

ZipSearchTask.buildRequest(model.zipCode.get()) .flatMap(ZipSearchTask::submitRequest) .flatMap(ZipSearchTask::parseResponse) .delay(5, TimeUnit.SECONDS) .subscribeOn(Schedulers.newThread())

.observeOn(AndroidSchedulers.mainThread()) .subscribe(mySubscriber);

Task

Listener

Base of my idea

Activity(Portrait)

Activity(Landscape)

DataModel

Observable

Web API(Search address)

share shareSubscriber

2. Task sharing with RxJavapublic class RxZipSearchActivity extends AppCompatActivity {

private MySubscriber mySubscriber;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

...mySubscriber = (MySubscriber) getLastCustomNonConfigurationInstance();

if (mySubscriber != null) { mySubscriber.activeActivity = this; }...

@Overridepublic Object onRetainCustomNonConfigurationInstance() { return mySubscriber;}

Can implement task sharing, Quite simple & safely

3. Progress dialog

private void showProgressDialog() { if (getSupportFragmentManager().findFragmentByTag(TAG_PROGRESS_DIALOG) == null) { new ProgressDialogFragment().show(getSupportFragmentManager(), TAG_PROGRESS_DIALOG); }}

public static class ProgressDialogFragment extends AppCompatDialogFragment {

@Overrideprotected void onResume() { super.onResume(); // まだ通信の途中だったら dialogを出す if (mySubscriber != null && !mySubscriber.isUnsubscribed()) { showProgressDialog(); }

● Avoid multiple dialog showing

● Subscriber can be a clue if to show progress dialog

Summary

Introduced my idea to implement simple WebAPI client app

We have efficient way in 2016 (databinding, RxJava)

Let’s discuss how you design / implement such application now?

(Source code intoduced in my presentation)https://github.com/tsuyoyo/roppongi-aar3-address-search-app

2. RxJava Can implement task sharing, Quite simple & safely

public class RxZipSearchActivity extends AppCompatActivity {

private static class MySubscriber extends Subscriber<List<String>> {

private RxZipSearchActivity activeActivity;

@Override public void onCompleted() { Log.d("TestTestTest", "onCompleted"); }

@Override public void onError(Throwable e) { notifyResult(e.getMessage()); }

@Override public void onNext(List<String> result) {

activeActivity.notifyResult(result);onCompleted();