ラムダ式によってAndroidアプリを簡単に書く!


はじめに

Java8では大きな変更の一つにラムダ式というのがあります。

2016年4月のAndroid Plugin for Gradle ,Revision2.1.0によってAndroidでもラムダ式が書けるようになりました。

Androidでラムダ式を使いたい
http://qiita.com/kamimoo/items/f4b3ef22ca0327e88e32

にてRetrolambdaでラムダ式が記述できるようですが、こちらはJava8のラムダ式しかサポートしていませんが、今回紹介するものでは他のJava8の機能もサポートしていると思います。

[追記]2016/10/03

jackでのlambda記法はいたるところでバグを踏み根源になります。
私の確認した中では最悪だったのがbintrayやmavenにライブラリをアップロードするときに失敗する。
とても見つけづらくて苦戦しました。
あとはrealmですね。こちらもjackだとうまく動きません。

そういう場合は迷わずretrolabmdaを使用してください。
まあjava8の他の機能を使いたいとかいう場合は今の所待つしかない気がします。


では実際に使うまでの準備

まずはgradleを2.1.0以上にします。
2.1.0以上だと2.2.0でもなんでもいいと思います。
最新は下記URLで確認してください。
https://services.gradle.org/distributions

gradle-wrapper.properties
...
...
...
#2.10-all.zipに書き換える
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip

次にprojectのbuild.gradleを書き換える

build.gradle(project)

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        //2.1.0に書き換える
        classpath 'com.android.tools.build:gradle:2.1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

次はModuleのbuild.gradleを書き換えます。紛らわしいので注意

build.gradle(Module)
android {
    ...
    ...
    defaultConfig {
        ...
        ...
        ...
        //jackOptionsを加える
        jackOptions {
            enabled true
        }

    }
    ...
    ...
    ...

    //コンパイルオプションを加える
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

これでGradle Syncを実行すると、晴れてJava8の機能を使うことができるようになります。

以下サンプルのAndroidアプリの一部で従来の記法とラムダ記法で書いた時の違いを比較してみます。
サンプルはボタンが押されたらニュースサイトからRSSを取得してパースしてTextViewにセットする例です。

Java8以前の記法

samplePast.java
if(v.getId() == R.id.R.id.sport) {
    handler = new Handler();
    Thread thread = new Thread() {
        @Override
        public void run() {
            try {
                XmlParser xmlParser = new XmlParser();
                xmlParser.getSelectXml("http://news.yahoo.co.jp/pickup/sports/rss.xml");
                sportNewsList = xmlParser.getList();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (IndexOutOfBoundsException e) {
                e.printStackTrace();
            }
        }
    };
    thread.start();
    try {
        //取得までに時間がかかるため
        Thread.sleep(3000);
    }catch (InterruptedException e){
        e.printStackTrace();
    }
    handler.post(new Runnable() {
        @Override
        public void run() {
            topicButton1.setText(sportNewsList.get(0));
            topicButton2.setText(sportNewsList.get(1));
            topicButton3.setText(sportNewsList.get(2));
                }
    });
}

Java8のラムダ式記法での場合

sampleRamda.java
//ソースコードの一部
if(v.getId() == R.id.sport) {
  handler = new Handler();
  Thread thread = new Thread(() -> {
      try {
          XmlParser xmlParser = new XmlParser();
          xmlParser.getSelectXml("http://news.yahoo.co.jp/pickup/sports/rss.xml");
          sportNewsList = xmlParser.getList();
      } catch (IOException e) {
          e.printStackTrace();
      } catch (IndexOutOfBoundsException e) {
          e.printStackTrace();
      }
    });
    thread.start();
    try {
        //取得までに時間がかかるため
        Thread.sleep(3000);
    }catch (InterruptedException e) {
        e.printStackTrace();
    }
    handler.post(() -> {
        topicButton1.setText(sportNewsList.get(0));
        topicButton2.setText(sportNewsList.get(1));
        topicButton3.setText(sportNewsList.get(2));
    });
}

このように大分すっきりしますね。
Kotlinも型セーフの設計はいいですがJavaも進化して変わり続けているので、来年の3月にはJava9も発表されますし!!
JavaSE9の発表が延期されるかもしれません。