gradleでJavaのmainメソッドを実行する

  • 0
    いいね
  • 0
    コメント

    Androidアプリを作ってるときに、アプリ本体とは別にJavaのアプリケーションを実行したい場合がありますよね?

    例えば、以下のようなときとか。

    • CSVファイルからSQLiteのrawデータを生成、アプリの初期データとして格納したい
    • CSVとかExcelの定義ファイルから、Javaのコードを自動生成して、アプリ側のファイルツリーに加えたい

    そんなとき、apkの生成と同じように、gradleで実行できたらいろいろ嬉しいですよね?

    実装

    まず、新たにmoduleを作成し、そのbuild.gradleに下記を追加します。
    (moduleの作成は、Android Studioから出来ますね)

    somemodule/build.gradle
    apply plugin: 'application'
    
    mainClassName = 'jp.co.hoge.fuga.Main'
    
    run {
        if (project.hasProperty('args')) {
            args project.args.split('\\s+')
        }
    }
    

    実行時のプロパティを、main関数の引数に置き換えています。
    'args'とか split しているあたりを変えることで、必要なシチュエーション毎に対応できるかと思います。

    そして、mainメソッドを持つクラスを作成します。

    Main.java
    package jp.co.hoge.fuga;
    
    public class Main {
        public static void main(String[] args) {
            System.out.println("args = " + Arrays.asList(args));
        }
    }
    

    とりあえず、引数に渡ってきている配列を出力します。

    settings.gradle に、moduleを追加したことを記載しておきます。

    settings.gradle
    include ':app', ':somemodule'
    

    実行

    ./gradlew somemodule:run -Pargs="/Users/foo/bar"
    

    とすると、標準出力に args = [/Users/foo/bar] が表示されます。
    args[0] に実行時のパラメータが渡ってきているので、あとは煮るなり焼くなりしたら良いと思います。

    入力ファイルパスと、出力ファイルパスを受け取るアプリを作ったとします。
    mainメソッドの、
    0番目の引数:入力ファイルパス
    1番目の引数:出力ファイルパス
    という具合にするには、

    somemodule/build.gradle
    run {
        if (project.hasProperty('in') && project.hasProperty('out')) {
            args = [project.in, project.out]
        }
    }
    

    として、

    ./gradlew convertanimation:run -Pin="/Users/hoge/fuga" -Pout="/Users/foo/bar"
    

    といった形で実行してやれば良さそうです。

    言い訳

    あんまりgroovy力やgradle力が無いので、「普通はこうする」みたいなのがあれば、教えてほしいです :bow: