kotlinx.android.synthetic は使わないほうがいいのか

2) Replaced kotlinx synthetic with findViewById

kotlinx.android.synthetic is no longer a recommended practice. Removing
in favour of explicit findViewById.

Sample updates: Fragment state, synth accessors (Ic472f90e) · Gerrit Code Review

Hey! Developer Advocate for Android at Google here!

I wanted to add a bit of background here. Kotlin Extensions with synthetic views was never intentionally “recommended” though that shouldn’t be taken as a recommendation to not use them. If they're working for you please feel free to continue using them in your app!

We’ve been shifting away from them (e.g. we don’t teach them in the Udacity course) because they expose a global namespace of ids that’s unrelated to the layout that’s actually inflated with no checks against invalid lookups, are Kotlin only, and don't expose nullability when views are only present in some configuration. All together, these issues cause the API to increase number of crashes for Android apps.

On the other hand, they do offer a lightweight API that can help simplify view lookups. In this space it's also worth taking a look at Data Binding which also does automatic view lookups - as well as integrates with LiveData to automatically update your views as data changes.

Today, there's a few options in this space that work:

Data Binding is the recommendation for view lookup as well as binding, but it does add a bit of overhead when compared to Android Kotlin Extensions. It's worth taking a look to see if this is a good fit for your app. Data Binding also allows you to observe LiveData to bind views automatically when data changes. Compared to Kotlin Extensions, it adds compile time checking of view lookups and type safety.

Android Kotlin Extensions is not officially recommended (which is not the same as recommendation against). It does come with the issues mentioned above, so for our code we're not using them.

Butter Knife is another solution that is extremely popular and works for both Kotlin and the Java Programming Language.

Reading through the comments here there's a lot of developers that are having great luck with Kotlin Extensions. That's great - and something we'll keep in mind as we look at ways to continue improving our APIs. If you haven't taken a look at Data Binding, definitely give it a shot.

As an aside, our internal code style guide is not intended to be directly applied outside of our codebase. For example, we use mPrefixVariables, but there's no reason that every app should follow that style.

Why kotlinx synthetic is no longer a recommended practice : androiddev

Jake他、著名な人々のコードを見ていると、「そもそも使ってない」ことは明らか。

そもそも、

「user_name」 と 「userName」

の気持ち悪さはありましたよね。

mobile - Android id naming convention: lower case with underscore vs. camel case - Stack Overflow

強制的に禁止はしてないけど、そういうことだろうと思う。

findViewById 万歳!

ButterKnife 万歳!

kotlin-examples/gradle/android-butterknife at master · JetBrains/kotlin-examples

「Google+」の終了が2019年8月から4月に繰り上げ 5250万人に影響の新たなバグ発見で - ITmedia NEWS


なぜ私は「プロジェクトのインポート」が正しくできなかったのか

なんとなくやっていたのですが。

なんかおかしいとは思っていたのですが。

インポートするとなんかディレクトリ構成がグダクダ。

2つあるはずの build.gradle が1つだったり、見えなかったり。

あれこれ他の設定をいじったり、不要なディレクトリを消したり、

インポートのたびにストレスとなってました。

なぜ?

プロジェクトのソース指定時に、

「ディレクトリ」

を選択ではうまくいかない。

しかし、

「プロジェクトルートのbuild.gradle ファイル」

までを選択するとその後もスムーズに進んでいく。

きちんと表示されました。

また、ひとつスッキリできました。


SQLDelight の データベースバージョン

「分かれば簡単だけど、分かるまで難しい」

そんなこと多いですよね。

なにを悩んでいたのか。というやつ。

SQLDelight は、1.0 となり、今現在、ドキュメントやリファレンスが少なくてはまります。

おおまかに「しくみ」を捉えてからやってみること大事です。

 

1.テーブル作成

テーブルを作成したい場合。SQLで、


CREATE TABLE player (
  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  number INTEGER NOT NULL,
  name TEXT NOT NULL,
  time TEXT DEFAULT (strftime('%s', 'now')),
  UNIQUE (number, name)
);

のようなものを書きますよね。

これは、Player.sq というファイルに書いて、所定の位置に置きます。

この位置はデフォルトでは、パッケージ名 com.example.testdelight の場合、


/app/src/main/sqldelight/com/example/testdelight/Player.sq

となります。

 

2.クエリー作成

プログラムコード上で利用したい「メソッド名」と、それに対するSQLを箇条書きにします。


selectAll:
SELECT *
FROM player;

insert:
INSERT INTO player(number, name)
VALUES (?, ?);

changes:
SELECT changes();

count:
SELECT COUNT(id)
FROM player;

これも、前述の Player.sq ファイルに追記します。

これで、テーブル周りの設定は終わりです。

 

3.スキーマのバージョン

ここが少し分かりづらかったのですが、

「201901281」を新バージョンにしたい場合、

「1を引いたもの」をファイル名として、

「201901280.sqm」

として置きます。

今回は、テーブル定義の変更はないので、中身なしの空ファイルです。

少し不思議な感じがしますが、書き出してみると分かってきます。

なお、このファイルを設定しなければ、適用されるバージョンは「1」となります。

 

4.ビルドして書き出す

ここでビルドすると、以下のようなファイルが書き出されます。

それぞれ以下のコードとなっています。

これらを使って、コードを書いていきます。

 

まとめ

既存の .db ファイルに対して、バージョン更新を行いたい場合のキモとなるのは、書き出される Database ファイル。


object Schema : SqlDriver.Schema {

     override val version: Int
         get() = 201901281 // 201801280 + 1

     // ...

     override fun migrate(
         driver: SqlDriver,
         oldVersion: Int,
         newVersion: Int
     ) {
         if (oldVersion <= 201901280 && newVersion > 201901280) { // same .sqm file name

           // from 201801280.sqm contents
           // ...

         }
     }
 }

.sqm のファイル名の数字が、

「新バージョンの数字」
「適用される既存.db のバージョンの数字」

を決める。

SQLDelight 1.0 使い方 #1
SQLDelight 1.0 使い方 #2
SQLiteのユーザバージョンを利用する - Basic
Pragma statements supported by SQLite