【AndroidStudio 3.0】「flavor dimension」とは何?

AndroidStudio 3.0 にアップデートしましたが,

こんな build.gradle で 以下のエラーです.


android {
  // ...
}

productFlavors {
  flavor1 {
    // ...
  }
}

buildTypes {
  release {
    // ...
  }
  debug {
    // ...
  }
}


Error:All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html

StackOverflowで調べてみると以下の記述で大丈夫と書かれている.

Android Studio 3.0 Flavor Dimension Issue - Stack Overflow


android {
  // ...

  flavorDimensions "default" // OK
  //flavorDimensions "versionCode" // OK

}

productFlavors {
  flavor1 {
    // ...
  }
}

buildTypes {
  release {
    // ...
  }
  debug {
    // ...
  }
}

これでビルドは通る.

なんだか気持ち悪いし意味が不明すぎますね.

 

試してみる

いろいろやってみましたが, 以下のような記述がOKです.


android {
  // ...

  flavorDimensions "a"
}

productFlavors {
  flavor1 {
    // ...
  }
}

buildTypes {
  release {
    // ...
  }
  debug {
    // ...
  }
}

productFlavor を複数にする.


android {
  // ...

  flavorDimensions "a"

}

productFlavors {

  flavor1 {
    // ...
  }

  flavor2 {
    // ...
  }

  flavor3 {
    // ...
  }

  flavor4 {
    // ...
  }

}

buildTypes {
  release {
    // ...
  }
  debug {
    // ...
  }
}

flavorDimensions で productFlavor を2段階に分ける.


android {
  // ...
  flavorDimensions "a", "b"
}

productFlavors {

  flavor1 {
    dimension "a"
    // ...
  }

  flavor2 {
    dimension "a"
    // ...
  }

  flavor3 {
    dimension "b"
    // ...
  }

  flavor4 {
    dimension "b"
    // ...
  }
}

buildTypes {
  release {
    // ...
  }
  debug {
    // ...
  }
}

dimension で階層化された Build Variant が作成される.

 

まとめ

もともと productFlavor では以下のようなものが設定できました.

- applicationId
- versionCode
- minSdkVersion
- versionName/Suffix
- ソースコードやリソースの位置
- dependencies

これらを階層化させたい場合に使うのがいいように思います.

まずは, 開発時の時間短縮でしょうか.


flavorDimensions "minSdkVersion", "others"

Migrate to Android Plugin for Gradle 3.0.0 | Android Studio

ビルド バリアントの設定 | Android Studio


ログ出力をクリッカブルにして該当行に素早く移動

Android Studio でのログ出力.

任意の文字列を出力する場合は,


Log.d("TEST", "テスト")

と書いておくと,

となります.

Kotlin では,


println("TEST テスト")

と書いてあげると,

となります.

以下のような文字列にすると,


println("TEST https://google.com/")

println("TEST (MainActivity.kt:100)")

と表示されて,

それぞれブラウザの該当ページや,

該当ファイルの該当行に直接クリックで遷移できるようになります.

ここで,

Exception().stackTrace[1]

を使うと, 記述した位置の該当ファイル名と行数が取得できるので,

インラインなユーテリティにします.


class LogUtils {

  companion object {

    private const val TAG : String = "TEST"

    @JvmStatic fun d(message: String) = Log.d(TAG, appendFileLine(message))
    @JvmStatic fun d(message: String, t: Throwable) = Log.d(TAG, appendFileLine(message), t)

    @Suppress("NOTHING_TO_INLINE") // ?
    private inline fun appendFileLine(message: String): String {
      val frame = Exception().stackTrace[1]
      return "$message (${frame.fileName}:${frame.lineNumber})"
    }

  }

}

あとは, 表示したいメッセージとともにお好みの場所で


LogUtils.d("テスト")

と書いておけば,

となって便利にデバッグに使えたり.


Android Studio エミュレータのネットワーク設定

最近は使えるのかな,とひさびさにエミュレータ...

はい,DNSエラー.

エミュレータ内にて.


generic_x86:/ $ ifconfig
lo        Link encap:UNSPEC
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope: Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:310 TX bytes:310

eth0      Link encap:UNSPEC    Driver virtio_net
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::5054:ff:fe12:3456/64 Scope: Link
          inet6 addr: fec0::5054:ff:fe12:3456/64 Scope: Site
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3506 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3523 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:270699 TX bytes:274244


generic_x86:/ $ getprop
...
[net.bt.name]: [Android]
[net.eth0.dns1]: [10.0.2.3]
[net.eth0.gw]: [10.0.2.2]
[net.gprs.local-ip]: [10.0.2.15]
[net.qtaguid_enabled]: [1]
[net.tcp.default_init_rwnd]: [60]
...

仮想ネットワークは正しく構築できているようですが.

Set Up Android Emulator Networking | Android Studio

結局これ,パソコン上のDNSに Google Public DNS アドレスを追記で繋がるようになります.

Firewall などはONのままでよいです.

DNSとして設定されたルータのローカルアドレスをうまくエミュレータ側で認識/変換できないのだろうと思われます.

ちなみに,接続成功時のパソコン内にて以下.

~$ cat /var/run/resolv.conf
#
# Mac OS X Notice
#
# This file is not used by the host name and address resolution
# or the DNS query routing mechanisms used by most processes on
# this Mac OS X system.
#
# This file is automatically generated.
#
search flets-east.jp iptvf.jp
nameserver 192.168.0.1
nameserver 8.8.8.8
nameserver 8.8.4.4

~ $ cat /etc/resolv.conf
#
# Mac OS X Notice
#
# This file is not used by the host name and address resolution
# or the DNS query routing mechanisms used by most processes on
# this Mac OS X system.
#
# This file is automatically generated.
#
search flets-east.jp iptvf.jp
nameserver 192.168.0.1
nameserver 8.8.8.8
nameserver 8.8.4.4

Run Apps on the Android Emulator | Android Studio

エミュレータ内にて setprop -> restart network で接続できたとしても毎回いちいち面倒です.

戻ろう、Genymotion に。
→ Genymotion 無料版 を入れる 2018