res ディレクトリは小分けにしたほうがいいのではないか

java ディレクトリ以下は, お好みで小分けして素早くたどりつけるのに,

1-A-m20R0Qve-eB4ishqZc_Q

ソースディレクトリの構成時にもっておくべき「会社別」のイメージ

res ディレクトリ以下ときたら, なんの整理もしなくて, 該当ファイルになかなか辿りつけない.

res ディレクトリ以下も, 共用/画面別に分けたりするのはどうでしょうか, と GoogleDeveloperExperts の方が言っておられます.

Android_Project_Structure_—_alternative_way_—_Google_Developer_Experts_—_Medium

小分けにしても, マージして読み取ってくれるんですね.


sourceSets {
    main {
        res.srcDirs = [
                'src/main/res-main',
                'src/main/res-screen/about',
                'src/main/res-screen/chat',
                'src/main/res-screen/home',
                'src/main/res-screen/login',
                ....
        ]
    }
}

「Project View」でしか利用できないそうですが.

Android Project Structure — alternative way — Google Developer Experts — Medium

In this case, both resource folders have the same priority. This means that if a resource is declared in both folders, the merge will fail and an error will be reported.

Resource Merging - Android Studio Project Site

マージ後に重複するファイルがあればエラーとなり, 各ディレクトリ同士の優先順位はなしのフラット扱いらしいです.

IDE自体にどんな便利なショートカットや検索機能があったとしても, 直感的にわかりやすい構成にしておきたいですよね!


熊本の状況を鮮明にドローンで撮影した動画を公開した国土地理院の仕事の早さ

【国土地理院】 阿蘇大橋周辺の土砂崩れ箇所_-_YouTube

国土地理院動画チャンネル - YouTube

なんとなく, 暗い空気の中, 明るい話題のように思えたりする.

やることが新しいし, 仕事が早い.

発足したばかりのこれかな.

国土地理院は3月16日より、国土交通省が推進する「i-Construction」の一環として、無人航空機(UAV:Unmanned aerial vehicle 通称ドローン)を使った測量環境の整備を開始します。具体的には、国土地理院内に「i-Construction推進本部」(会議体)を設置するほか、UAV技術者を育成し、i-Construction向けの測量に必要な指導・助言、災害時には自らが現場の撮影・測量を行う「国土地理院ランドバード」(体制)を発足します。
これにより、建設現場における生産性の向上と災害対応時のUAV活用を推進します。

無人航空機(UAV)を使った測量を支援する「国土地理院ランドバード」を発足 ~「i-Construction」を推進し、建設現場の生産性向上に貢献~|国土地理院

これだけ鮮明に危険なく状況を把握できると, いろいろ役に立つと思われます.

がんばれ熊本!!

菅直人政権の方がずっとマシだ!安倍政権の熊本地震対応に批判が集まる - NAVER まとめ


Android Studio のショートカットを覚えられない人のための最小限な2つ

こんな便利な機能があったのかと驚きました!!

(About) 10 Things You (Probably) Didn’t Know You Could do in Android Studio — Google Developers — Medium

いろいろあって便利ですよね!!

しかし「ここで!!」「いざ!!」 というときに忘れてる.

自分が頻繁に使うものだけ覚えればいいのだろうが思い出せない.

結局, ネットで検索することになり, Windows や Mac で微妙にキーが違ったり.

Ctl や Alt などの特殊キーの組み合わせは覚えづらい.

覚えられない人はどれから覚えたらいいのか.

Top 10 Android Studio Shortcuts - InnovateCode

上から2つのショートカットだけ覚えておこう.

機能の検索 - Ctl + Shift + A
テキストの検索 - Shift 二回押し

一つ目の「Find Action」(Ctl + Shift + A) で使える比較的覚えやすいキーワードだけ覚えておこう

completion
template
find
jump
postfix
search
replace
recently
keymap
auto
last
build
...

_About__10_Things_You__Probably__Didn’t_Know_You_Could_do_in_Android_Studio_—_Google_Developers_—_Medium

指で覚えてしまうまでは, これでいいや!!

AndroidStudioの設定場所やショートカットは「FindAction(テキストランチャー)」が捗りすぐる件


プログラマーのヘルプにもなる DuckDuckGo「Programming Instant Answers」

成長を続けているようです. かわいいアヒルでお馴染み(?)の.

DuckDuckGo

DuckDuckGo

こんな機能がアナウンスされています.

DuckDuckGo Blog : How we're trying to help programmers

プログラミング言語とキーワードの組み合わせを入力して検索するとヘルプのように結果が表示されます.

チートシートなども結果として準備されていたりします.

bash_time_-_DuckDuckGo

cheat_sheet_php_-_DuckDuckGo

strpos_php__PHP__-_DuckDuckGo

loop_python__Python__-_DuckDuckGo

hello_world_mysql_-_DuckDuckGo

hello_world_java_-_DuckDuckGo

hello_world_perl_-_DuckDuckGo

現在は, まだ言語によってまだばらつきがあるようですが, 多くの言語をカバーしようとしているようです.

Programming_IA_Coverage_·_duckduckgo_duckduckgo_Wiki

Programming IA Coverage · duckduckgo/duckduckgo Wiki

公開されているドキュメントをみてみるといろいろな試みをおこなっているようで非常に興味深いです.

How_Instant_Answers_Work___DuckDuckHack_Docs

How Instant Answers Work | DuckDuckHack Docs

DuckDuckGoとは?

たしか「プライバシーな情報は取得しない」というフレーズだけが聞こえてきてたように思うのですが, こちらはこちらで進化を続けていたのですね.

早くもっと大きなアヒルに育って欲しいですね.


直感的に理解する RxJava その4: Reactive Android

ReactiveX

その1, その2, その3では, RxJava がどのように機能するかを書きました. Androidアプリの開発では, それをどのように利用するのでしょうか. ここでは Android開発者に向けての実践的なことを書いてみようと思います.

RxAndroid

RxAndroid は Android用の RxJavaエクステンションで, より簡単に利用できるようバインディングなどを含んだものです.

まず最初に, AndroidScheduler です. これは, 既存の Android のもつスレッド処理を考慮したスケジューラを提供します. 別に, UIスレッド処理に関係するコードは必要ありません.
AndroidSchedulers.mainThread() を利用するだけです.


retrofitService.getImage(url)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(bitmap -> myImageView.setImageBitmap(bitmap));

もし, あなたが自作の Handler を利用しているのであれば HandlerThreadScheduler を利用して スケジューラとそれをリンクしましょう.

次に, AndroidObservable には, Androidライフサイクル内で有効に利用できる機能があります. それは bindActivity() と bindFragment() です. Observable に対してAndroidSchedulers.mainThread() を使うことで自動的に追加でき, Activity や Fragment が終了した場合にはアイテムを発することを停止することができます.


AndroidObservable.bindActivity(this, retrofitService.getImage(url))
    .subscribeOn(Schedulers.io())
    .subscribe(bitmap -> myImageView.setImageBitmap(bitmap));

また, AndroidObservable.fromBroadcast() は便利です. これは, BroadcasrReceiver のように利用することができる Observable を作成できます. 以下が, ネットワーク接続状態が変化したときに通知するコードです.


IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
AndroidObservable.fromBroadcast(context, filter)
    .subscribe(intent -> handleConnectivityChange(intent));

その他に, View にバインディングできる ViewObserbable が2つあります. あるタイミングで View がクリックされたというイベントを取得したい場合には ViewObserbable.clicks(), TexitView が持っているテキストの変更を監視する ViewObservable.text() があります.


ViewObservable.clicks(mCardNameEditText, false)
    .subscribe(view -> handleClick(view));

Retrofit

Android用RESTクライアントの有名なライブラリである Retrofit は RxJava をサポートしています.

通常ではコールバックを追加して非同期処理を実装します.


@GET("/user/{id}/photo")
void getUserPhoto(@Path("id") int id, Callback<Photo> cb);

RxJava を利用していれば, これの代わりに Observable を返すことができます.


@GET("/user/{id}/photo")
Observable<Photo> getUserPhoto(@Path("id") int id);

これだけで Observable に変換することができます. データを取得するだけでなく, 変換も同時に行います.

また, Retrofit は Observable に対して, 簡単に複数のRESTコールを合成することができます. 以下のサンプルでは, 写真データとそのメタデータを取得したいとします. zip を利用して取得結果を合成します.


Observable.zip(
    service.getUserPhoto(id),
    service.getPhotoMetadata(id),
    (photo, metadata) -> createPhotoWithData(photo, metadata))
    .subscribe(photoWithData -> showPhoto(photoWithData));

これに似たサンプルをその2 (flatMap() を利用) で紹介しました. 複数のREST処理は RxJava + Retrofit でこれだけ簡単に利用できるのです.

今までのコードや処理に時間のかかるコード

Retrofit は適切な Observable を返すことができることは分かりましたが, その他のライブラリを利用している場合はどうなるでしょうか. Observable に変換するコードが必要となるのでしょうか? すべてを変更せずにそのコードをどのようにして利用することができるのでしょうか ?

ほとんどの場合, そのコードから Observable を作成するには Observable.just() とObservable.from() で十分であると思います.


private Object oldMethod() { ... }

public Observable<Object> newMethod() {
    return Observable.just(oldMethod());
}

oldMethod() が短時間の処理であればこれで問題ないでしょう. しかし, 時間のかかる処理であればどうなるでしょう? Observable.just() の前に oldMethod() が実行されスレッドをブロックしてしまいます.

この問題の対応策として, 時間のかかる処理を defer() でラップするという技を私はいつも利用しています.


private Object slowBlockingMethod() { ... }

public Observable<Object> newMethod() {
    return Observable.defer(() -> Observable.just(slowBlockingMethod()));
}

このようにすると Observable が subscribe されるまでは slowBlockingMethod() から結果を返さないようになります.

ライフサイクル

最もややこしい部分です. Activity のライフサイクルに対しての操作はどうなるでしょう? 2つの問題がいつも登場します.

1.「Configuration が変更されるとき(端末の回転時など) に Subscription が継続している」

Retrofit を利用してRESTコールを行い, 外部から取得したデータを ListView に表示するとします. もし, ユーザが画面を回転させたらどうなるでしょうか? そのリクエストを継続したい場合はどうすればよいのでしょうか?

2. Observable が Context を参照したままでいるので メモリーリークが発生する.

この問題は Context を保持している Subscription が引き起こしています. View と連携しているときはわかりやすいですが, なぜか保持しています. 最終的には, たくさんのメモリーを食いつぶしてしまいます.

残念ながら, それぞれの問題には一発で解決できる方法はありませんが, 分かりやすく理解するためのいくつかのガイドラインがあります.

最初の問題は, RxJava のもつキャッシュ機能で解決できます. それを使うことで同じ Observable が重複して動かないように unsubscribe/resubscribe できます. cache() や replay() を使うことで, たとえ unsubscribe してる場合でさえ 遅延なしのリクエストを継続することができます. このことは, Activity が再作成後の新しい Subscription によりレジュームできることを意味しています.


Observable<Photo> request = service.getUserPhoto(id).cache();
Subscription sub = request.subscribe(photo -> handleUserPhoto(photo));

// ...When the Activity is being recreated...
sub.unsubscribe();

// ...Once the Activity is recreated...
request.subscribe(photo -> handleUserPhoto(photo));

注意点としては, 両方のタイミングで同じキャッシュされたリクエストを利用していることです. 遅延のないコールは一度しか行われません. どこにリクエストを保存するかはあなた次第ですが, ライフサイクルを考慮しながら, ライフサイクルの影響を受けないどこかに保存しなければなりません.

二つ目の問題は, ライフサイクルを考慮しながらの Subscription に対しての適切な unsubscribe で解決できます. これの一般的な方法は CompositeSubscription を使うことですべての Subscription を保持し, onDestroy() や onDestroyView() のタイミングに一括で unsubscribe する方法です.


private CompositeSubscription mCompositeSubscription
    = new CompositeSubscription();

private void doSomething() {
    mCompositeSubscription.add(
        AndroidObservable.bindActivity(this, Observable.just("Hello, World!"))
        .subscribe(s -> System.out.println(s)));
}

@Override
protected void onDestroy() {
    super.onDestroy();

    mCompositeSubscription.unsubscribe();
}

このように Activity/Fragment で CompositeSubscription を持つことで, それぞれを追加し, その後, 一括ですべてを unsubscribe することができます.

注意することは, 一度 CompositeSubscription.unsubscribe() するとそれは再利用できません. 再度利用する場合は 新しい CompositeSubscription を作成して利用しなければなりません.

という形でどちらの問題もコード追加で解決できます. これらのボイラープレートなしに問題を解決できる天才がいつか現れて欲しいです.

あとがき

Android についてはこれだけではありません. RxJava はこれからも更新され, Android にもさらに対応されていくでしょう. みなさんがこれらのことをさらに理解しようとするとき, RxAndroid はまだ開発中で, よいサンプルがまだありません. 私がここで提示したサンプルはこれから一年間は興味深いものになると思います.

その間, RxJava がコーディングを簡単にするだけのものだけでなく, もっとおもしろいものを探します. もしあなたがまだ納得していなければ, いつか私を見つけてください, それについてビールを飲みながら話します.

[原文] Grokking RxJava, Part 4: Reactive Android

直感的に理解する RxJava その1: 基本的な構成

直感的に理解する RxJava その2: Operator

直感的に理解する RxJava その3: リアクティブであることのメリット