あなたは Android Architecture Component をどう思いますか?

ある人々のTwitter上の会話。ザクッと翻訳サービスを利用して眺めてみます。

Frankly, the expectation is that all applications of a considerable size already use some form of DI. Thus providing yet another way to pass dependencies via context is an overkill. All "non-DI" facilities are just gimmicks/workarounds for cases when there is no DI.

率直に言って、かなりの数のアプリケーションがすでにDIを使用している。したがって、コンテキストを介して依存関係を渡すためのさらに別の方法を提供するのはやり過ぎです。すべての「非DI機能」は、DIがない場合のギミック/回避策にすぎません。

On Android this sadly isn't the case. We seem to relish in bad architecture.

It's either "Why do I have to pass an executor/scheduler/dispatcher? So much boilerplate!" or "Why can't I test on the JVM? This library is poorly designed!"

Maybe KEEP-87 will save us from ourselves?

Androidでは、これは悲しいことではありません。悪いアーキテクチャーで大喜びしているようです。

「executor / scheduler / dispatcher を渡す必要があるのはなぜですか? かなりのボイラープレートです。」、「なぜJVMでテストできないのですか?このライブラリは適切に設計されていません。」

多分KEEP-87は私達を私達自身から救うのだろうか?

👉 [Kotlin] KEEP87 brings compiler-driven dependency injection without frameworks : androiddev 

On unrelated note. (disclaimer: I'm not an Android developer) I have a feeling that something is broken in testing or architecture approaches here. I've been writing huge (1M+ LOCs) UI apps for more than a decade and never had to use either DI or statics to make them testable.

無関係なメモについて。 (免責事項:私はAndroidの開発者ではありません)何かがここでテストやアーキテクチャのアプローチで壊れていると感じています。私は10年以上にわたって巨大な(1M + LOC)UIアプリを書いてきました。そしてそれらをテストするために DI や statics を使う必要は決してありませんでした。

Android never had architecture guidelines and the docs encouraged doing all the wrong things to make the tutorials easy. Basically equivalent to writing everything in main(). Even now almost all of the architecture offerings treat symptoms of this legacy and not the disease.

Androidはアーキテクチャのガイドラインがなかったので、チュートリアルを簡単にするためにすべての間違ったことをすることをドキュメントを奨めてきました。基本的にmain() ですべてを書くのと同じです。現在でも、ほとんどのアーキテクチャがこの遺産の症状を治療していて、疾患を治療していません。

👉 Roman Elizarov on Twitter: "@JakeWharton Frankly, the expectation is that all applications of a considerable size already use some form of DI. Thus providing yet another way to pass dependencies via context is an overkill. All "non-DI" facilities are just gimmicks/workarounds for cases when there is no DI." / Twitter 

みなさんはどう思っていますか?

Roman Elizarov
@relizarov
Team Lead @JetBrains, working on @Kotlin coroutines and libs, sports programming/ICPC, concurrency & algorithms, math/quantitative finance; formerly @Devexperts

👉 Roman Elizarov (@relizarov) / Twitter 

Jake Wharton
@JakeWharton
Opinions expressed here are my own, not those of my company. They made me write this because I complain about Inbox going away so much.

👉 Jake Wharton (@JakeWharton) / Twitter 


Android Q beta4 のOTAが来ない理由

リリースアナウンスからもう5日間くらい経ってるのに!

Today we’re releasing Beta 4 with the final Android Q APIs and official SDK -- the time is now to get your apps ready for the final release later in the summer!

You can get Beta 4 today on Pixel devices by enrolling here. If you're already enrolled and received the Beta 3 on your Pixel device, you'll automatically get the update to Beta 4. Partners participating in the Android Q Beta program will also be updating their devices to Beta 4 over the coming weeks.

👉 Android Developers Blog: Android Q Beta 4 and Final APIs! 

来ない。

どうやら、問題発生のためGoogleが配布を一旦停止してる模様。

Update 2 (6/6/19 @ 9:25 AM ET): Google has halted the Android Q Beta 4 OTA update due to bootlooping issues.

Update 2: OTA Halted
Numerous Pixel owners reported that their devices were bootlooping after installing the Android Q Beta 4 OTA update. It appeared to mostly affect Pixel 2 XL owners, but a few Pixel 3 owners also had the problem. A factory reset fixed things, but this is obviously a problem. Google has officially halted the OTA on all Pixel phones as they investigate the situation.

We’re aware of an issue with Android Q Beta 4 related to installing updates. We’ve temporarily paused Beta 4 OTA updates to all Pixel devices as we investigate the issue. We apologize for any inconvenience, and will provide an update once the issue is resolved.

👉 [Update: OTA halted] Android Q Beta 4 is here for the Google Pixel, API 29 publishing now available 

Update:
We're aware of an issue with Android Q Beta 4 related to installing updates. We've temporarily paused Beta 4 OTA updates to all Pixel devices as we investigate the issue. We apologize for any inconvenience, and will provide an update once the issue is resolved.

Note: this post was edited to reflect that Beta 4 updates have now been paused on all devices.

👉 Android Q Beta 4 now available! : android_beta 

ブート周りは不具合は、これまでもよくありました。

再開されるのは、いつなのか。

更新されたらレビューしたいと思います。

👉 Android Q Release Watcher 
👉 Android Q beta 4 update temporarily halted due to installation woes 


【MVVM】Transformations.switchMap() の使い方

👉 ViewModels and LiveData: Patterns + AntiPatterns – Android Developers – Medium 
👉 LiveData beyond the ViewModel — Reactive patterns using Transformations and MediatorLiveData 

LiveData をリアクティブに操作できるこのユーティリティメソッド。

LiveData を変換します。
これから返されるLiveData オブジェクトを Observe しておけば、Observer のライフサイクルを考慮しながら、データを変換することができます。lazy に処理され、呼び出しや依存関係の記述なしに、ライフサイクル関連の動作が引き継がれます。

👉 Transformations | android.arch.lifecycle.Transformations  |  Android Developers 

実体は MediatorLiveData のユーティリティ

ソースコードを見てみます。


@SuppressWarnings("WeakerAccess")
public class Transformations {

    private Transformations() {
    }

    @MainThread
    public static <X, Y> LiveData<Y> map(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, Y> mapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            @Override
            public void onChanged(@Nullable X x) {
                result.setValue(mapFunction.apply(x));
            }
        });
        return result;
    }

    @MainThread
    public static <X, Y> LiveData<Y> switchMap(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, LiveData<Y>> switchMapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            LiveData<Y> mSource;

            @Override
            public void onChanged(@Nullable X x) {
                LiveData<Y> newLiveData = switchMapFunction.apply(x);
                if (mSource == newLiveData) {
                    return;
                }
                if (mSource != null) {
                    result.removeSource(mSource);
                }
                mSource = newLiveData;
                if (mSource != null) {
                    result.addSource(mSource, new Observer<Y>() {
                        @Override
                        public void onChanged(@Nullable Y y) {
                            result.setValue(y);
                        }
                    });
                }
            }
        });
        return result;
    }
}

👉 Cross Reference: Transformations.java 

ソースコードより、これは、1:1 の MediatorLiveData を使うための便利ツールです。


class MainViewModel {
  val repositoryResult = Transformations.switchMap(userManager.user) { user →
     repository.getDataForUser(user)
  }
}

複数に変換したい場合は、直接 MediatorLiveData を使うのが良いでしょう。


val liveData1: LiveData<Int> = ...
val liveData2: LiveData<Int> = ...

val result = MediatorLiveData<Int>()

result.addSource(liveData1) { value →
    result.setValue(value)
}
result.addSource(liveData2) { value →
    result.setValue(value)
}

まとめ

ViewModel 内で、その下にある Repository との間で使います。

View (Activity / Fragment) のライフサイクルにも考慮されています。

ViewModel内で、データの id からその詳細情報の取得をしたり、検索文字列をフィルターとしてデータ抽出したり、などに使うことが多いようです。

👉 MediatorLiveDataとTransformationsでViewModelを効果的に使う