JetBrains Toolbox で Android Studio の Stable/Beta/Canary が同時に管理できる?

これ。

The New Toolbox App 1.13 with Android Studio inside! | JetBrains Blog

Jakeも何か言っています。


JetBrains のIDEのパッケージ群を管理したり起動できるランチャーのようです。

それに、新たに AndroidStudio も使えるようになった。ということでしょうか。

インストールしてみます。



 

Toolbox Extension

そして、それをChrome上のGitHub画面から起動できるChromeエクステンションも登場しています。

JetBrains Toolbox Extension - Chrome ウェブストア

GitHubページに表示されるアイコンをクリックすると、ソースをダウンロードして、ローカルで起動しようとします。

 

Toolbox(本体)

アドビのパッケージ管理のウィジェットにも似た雰囲気です。

OS画面上部の常駐のバー(?)にアイコンが表示されるのでそれから起動します。

ローカル内のプロジェクトの選択してのIDEの起動と、それぞれのIDEパッケージのバージョン管理が可能になります。

アドビのパッケージマネージャ的なやつと思ったらいいでしょう。

Android Studio/Intellij は、複数のバージョンが並行利用できそうです。

無料です。

👉 AndroidStudio 利用する Java (JDK) の選択・設定の方法 hatena-bookmark
👉 Android Studio Chipmunk の起動時がかわいい件 


そんなに Mac 日本語音声入力は使えないのか?

こんな記事。

Google Chrome上でマイクから録音した声をリアルタイムで文字に書き起こしてくれる「The Recording Studio」 - GIGAZINE

ん。

そんなに、「OSの日本語音声入力」は使えないのか?

Mac でテキストを音声入力する - Apple サポート

ということでやってみたけど、まあ使える。



一体、なんなの。


今どきのアプリに必須な「複数のソースからのデータ取得」の実装

少し古いですが、ふと思い出した記事です。
ネットワークを使ったすべてのアプリに必須な考え方だと思います。

Loading data from multiple sources with RxJava

ネットワーク経由で問い合わせするデータがある場合、必要なときにそのまま取得することができますが、ディスクやメモリにキャッシュするほうが効率的です。

1. たまにネットワーク経由で新鮮なデータを取得する。
2. それ以外は、その結果をキャッシュしてできるだけ早く取得する。

RxJava を使ってこの実装をすると良いです。

 

基本となる流れ

Observable を使って、ネットワーク、ディスク、メモリーのそれぞれから取得します。

シンプルに2つのオペレーター concat() と first() を使います。

concat() は、複数の Observable を並び順に合成して、first() はその並び順から最初のものを実行します。よって、concat().first() とすると、複数のソースから最初のものが取得されます。


// Our sources (left as an exercise for the reader)
Observable<Data> memory = ...;
Observable<Data> disk = ...;
Observable<Data> network = ...;

// Retrieve the first source with data
Observable<Data> source = Observable
  .concat(memory, disk, network)
  .first();

このパターンの鍵となるのは、concat() が 必要なときにだけ、それぞれの子Observableを subscribe することです。

first() はシーケンスを早く止めるので、データがキャッシュされている場合に不要な遅いソースの問い合わせはありません。 言い換えれば、メモリから結果が返された場合、ディスクやネットワークにアクセスする必要はありません。 逆に、メモリとディスクがデータを持っていない場合は、新しくネットワークリクエストを行います。

 

データの保存

当然、次のステップは、ソースが入ってきたときにそれを保存することです。ネットワーク要求の結果をディスクに保存したり、ディスクへのリクエストをメモリにキャッシュしなければ、何の意味もありません。上記のコードは、常にネットワークリスエストを行うだけです。

私の考えた対策は、それぞれのソースがそれを発行するときにデータを保存/キャッシュすることです。


Observable<Data> networkWithSave = network.doOnNext(data -> {
  saveToDisk(data);
  cacheInMemory(data);
});

Observable<Data> diskWithCache = disk.doOnNext(data -> {
  cacheInMemory(data);
});

これで、networkWithSaveとdiskWithCacheを使用した場合、データはロード時に自動的に保存されます。

(この方法のもう1つの利点は、networkWithSave / diskWithCache はどこでも使用できることです。)

 

古いデータ

このままでは、古いままのデータが常に返されます。新鮮なデータの取得のために、たまにはサーバから取得しなければなりません。

解決策は、first() で。これはフィルタリングも実行できます。価値のないデータを除去するように設定します。


Observable<Data> source = Observable
  .concat(memory, diskWithCache, networkWithSave)
  .first(data -> data.isUpToDate());

これで、「最新」と見なされる最初のアイテムのみを発行します。したがって、そのデータソースが古い場合は、新しいデータが見つかるまで次のソースに進みます。

 

first() の代わりに takeFirst()

first() の代わりに takeFirst() を使うこともできます。

2つの違いは、いずれのソースも有効なデータを発行しない場合、first()は NoSuchElementException をスローするのに対し、takeFirst() は例外なしで完了することです。

どちらを使用するかは、データ不足を明示的に処理する必要があるかどうかによって異なります。

dlew/rxjava-multiple-sources-sample: Sample code demonstrating loading multiple data sources via RxJava