マルチモジュール構成に便利な「Dependency Graph」を書き出して視覚化する

まずは、開発環境にいれておきます。

グラフの書き出しに必要です。


$ brew install graphviz

Graphviz - Graph Visualization Software



つづいて、確認するマルチモジュールプロジェクト の build.gradle に追記。


apply from: file('gradle/dependencyGraph.gradle')

該当位置に、gradleタスクを記述したファイルを置きます。

学習コストがかかるので、安定のJakeコードをそのままコピペで

まずは稼動させて、モチベーションを上げて進みましょう。


# gradle/dependencyGraph.gradle

task projectDependencyGraph {
  doLast {
    def dot = new File(rootProject.buildDir, 'reports/dependency-graph/project.dot')
    dot.parentFile.mkdirs()
    dot.delete()

    dot << 'digraph {\n'
    dot << "  graph [label=\"${rootProject.name}\n \",labelloc=t,fontsize=30,ranksep=1.4];\n"
    dot << '  node [style=filled, fillcolor="#bbbbbb"];\n'
    dot << '  rankdir=TB;\n'

    def rootProjects = []
    def queue = [rootProject]
    while (!queue.isEmpty()) {
      def project = queue.remove(0)
      rootProjects.add(project)
      queue.addAll(project.childProjects.values())
    }

    def projects = new LinkedHashSet<Project>()
    def dependencies = new LinkedHashMap<Tuple2<Project, Project>, List<String>>()
    def multiplatformProjects = []
    def jsProjects = []
    def androidProjects = []
    def javaProjects = []

    queue = [rootProject]
    while (!queue.isEmpty()) {
      def project = queue.remove(0)
      queue.addAll(project.childProjects.values())

      if (project.plugins.hasPlugin('org.jetbrains.kotlin.multiplatform')) {
        multiplatformProjects.add(project)
      }
      if (project.plugins.hasPlugin('kotlin2js')) {
        jsProjects.add(project)
      }
      if (project.plugins.hasPlugin('com.android.library') || project.plugins.hasPlugin('com.android.application')) {
        androidProjects.add(project)
      }
      if (project.plugins.hasPlugin('java-library') || project.plugins.hasPlugin('java')) {
        javaProjects.add(project)
      }

      project.configurations.all { config ->
        config.dependencies
                .withType(ProjectDependency)
                .collect { it.dependencyProject }
                .each { dependency ->
          projects.add(project)
          projects.add(dependency)
          rootProjects.remove(dependency)

          def graphKey = new Tuple2<Project, Project>(project, dependency)
          def traits = dependencies.computeIfAbsent(graphKey) { new ArrayList<String>() }

          if (config.name.toLowerCase().endsWith('implementation')) {
            traits.add('style=dotted')
          }
        }
      }
    }

    projects = projects.sort { it.path }

    dot << '\n  # Projects\n\n'
    for (project in projects) {
      def traits = []

      if (rootProjects.contains(project)) {
        traits.add('shape=box')
      }

      if (multiplatformProjects.contains(project)) {
        traits.add('fillcolor="#ffd2b3"')
      } else if (jsProjects.contains(project)) {
        traits.add('fillcolor="#ffffba"')
      } else if (androidProjects.contains(project)) {
        traits.add('fillcolor="#baffc9"')
      } else if (javaProjects.contains(project)) {
        traits.add('fillcolor="#ffb3ba"')
      } else {
        traits.add('fillcolor="#eeeeee"')
      }

      dot << "  \"${project.path}\" [${traits.join(", ")}];\n"
    }

    dot << '\n  {rank = same;'
    for (project in projects) {
      if (rootProjects.contains(project)) {
        dot << " \"${project.path}\";"
      }
    }
    dot << '}\n'

    dot << '\n  # Dependencies\n\n'
    dependencies.forEach { key, traits ->
      dot << "  \"${key.first.path}\" -> \"${key.second.path}\""
      if (!traits.isEmpty()) {
        dot << " [${traits.join(", ")}]"
      }
      dot << '\n'
    }

    dot << '}\n'

    def p = 'dot -Tpng -O project.dot'.execute([], dot.parentFile)
    p.waitFor()
    if (p.exitValue() != 0) {
      throw new RuntimeException(p.errorStream.text)
    }

    println("Project module dependency graph created at ${dot.absolutePath}.png")
  }
}

projectDependencyGraph.gradle · JakeWharton/SdkSearch

以上の2ファイルに対する作業を、

シンプルなマルチモジュール構成のコードをお借りしてやってみます。

あとは、タスク実行するだけ。

以下動画のようにPNG画像としてグラフが書き出されます。



DoroidKaigi2019 コードでも利用されていますね。

conference-app-2019/dependencyGraph.gradle at master · DroidKaigi/conference-app-2019

便利です。


Android で ダークモード

流行りですか、ダークモード。

Mac Mojave とか Chrome とか、

画面はダークな方面に進んでいるようですが。

How to use Dark Mode on your Mac - Apple Support

本当に目に優しいのかどうかは知らんけども、

バッテリーには間違いなく優しそう。

Android端末でも設定してみましょう。

端末のテーマ


設定 (Settings)

↓

ディスプレイ (Display)

↓

詳細設定 (Advanced)

↓

端末のテーマ (Device Theme)

↓

ダーク (Dark)

これだけでは、変更されなかったり。

以下「夜間モード」と関係を持ちながらテーマ変更されているようです。

夜間モード


設定 (Settings)

↓

システム (System)

↓

詳細設定 (Advanced)

↓

開発者向けオプション (Developer Options)

↓

夜間モード (Night Mode)

↓

常にON



階層が深い「設定」項目は上部検索窓から検索できますが、日本語の場合、それぞれキーワードは

「端末のテーマ」

「夜間モード」

くらいになりそうです。

その他、Chrome など各アプリも個別に対応をしてたり、してなかったり。

微妙です。

👉 Chrome ダークモードの選択しているタブが見づらい 

しかし、

最近の日本語を利用しての検索ワードの選択は難しくなってきてません?

How to enable Android dark mode everywhere it's available - 9to5Google


Android人気ニュース速報 2019-02-27

Xperia 1

【西田宗千佳のRandomTracking】「Xperia 1」が示すソニー独自の価値。マスモニ譲りの発色、21:9の狙い - AV Watch

Xperia 1を、ソニーが発表。スペック、発売日など。4KのOLED、トリプルレンズカメラなどを搭載。縦に長い - ビジョンミッション成長ブログ

「Xperia 1」発表、世界初4K有機EL・縦長ディスプレイにトリプルカメラ。日本での発売も予告

ソニーモバイル、世界初の瞳AF&4K有機EL搭載6.5型スマホ「Xperia 1」 ~ミッドレンジスマホの「Xperia 10/10 Plus/L3」も発表 - PC Watch

 

FIDO2

「Android」がFIDO2認定を取得、パスワードなしでログイン可能に - CNET Japan

FIDO2認証でAndroid上のアプリやサービスのパスワードレス化がさらに進む | TechCrunch Japan

Android Now FIDO2 Certified, Accelerating Global Migration Beyond Passwords - FIDO Alliance

 

Nokia9

驚異の5眼カメラ!白黒カメラを3つ積んだNokia 9 PureView正式発表 – すまほん!!

5眼カメラ搭載スマホ「Nokia 9 Pure View」発表 7万円台

 

Mate X

OPPOも折りたたみスマホ。見た目はHUAWEI Mate Xそっくり

ファーウェイの折りたたみスマホ「Mate X」は、初代端末としてはまあまあの出来 | ギズモード・ジャパン

HUAWEI、折りたたみ5Gスマホ「Mate X」発表

【更新終了】29万円! 折りたたみスマホ「Huawei Mate X」が出たぞ! Huaweiの発表会を実況しました(24日22時〜) | ギズモード・ジャパン