groovy789's blog

技術系備忘録φ(..)メモメモ

祝!アプリリリース

Groovyで作成したandroidアプリをリリースしました(*´ω`*)

パスワード管理 - Google Play の Android アプリ

パスワード管理できるツールです。


特徴

  1. groovyで書かれている(groovy only!!!)

。。。以上


groovyで書かれたandroidアプリがどの程度動くか試したい場合はどうぞ(・∀・)


今後の実装予定
(つーか、本当は公開する前に実装しとけ的な・・・)

  1. パスワード自動作成機能
  2. パスワード有効期限設定
  3. 一覧のフィルタ
  4. 一覧のソート
  5. データのカテゴリ分け
  6. インポート/エクスポート

ぼちぼち実装していきますか(´・ω・`)

Groovyで関数インターフェースをクロージャで実装する

関数インターフェースとはjava8で追加されたあれです(´・ω・`)
インターフェースにメソッド定義が1つしかないやつです。
Runnableとかが代表的ですかね~。

goovyでどうやって書けるのかちょっと調べたのでφ(..)メモメモ

[java8]

public class TestRunnable {
    public static void main(String[] args) {
        new Thread(() -> System.out.println("Hello World")).start();
    }
}

[groovy]

class TestRunnable {
    static main(args) {
        new Thread({ println "Hello World" } as Runnable).start()
    }
}


androidでイベントを処理するときにどうやって書いたらいいのかちょっと悩んだので(´・ω・`)

[groovy]

    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity)
        builder.title = R.string.dialog_title
        builder.message = R.string.dialog_msg
        // OKボタン
        builder.setPositiveButton(R.string.dialog_positive, { d, w -> println "Ok" } as DialogInterface.OnClickListener)
        // キャンセルボタン
        builder.setNegativeButton(R.string.dialog_negative, { d, w -> println "Cancel" } as DialogInterface.OnClickListener)
        builder.create()
    }

これでまた一歩前進だー(*´ω`*)

Scalaでプレースホルダの話

うーん。よくわからん(´・ω・`)

というわけでまとめてみた。

  1. 個別の値としての「_」
  • 引数が1個の場合
    val funcA1: (Int) => Int = (n: Int) => n + 1
    val funcA2: (Int) => Int = (n) => n + 1
    val funcA3: (Int) => Int = n => n + 1
    val funcA4: (Int) => Int = _ + 1
    // 引数が複数の場合
    val funcB1: (Int, Int) => Int = (a: Int, b: Int) => a + b
    val funcB2: (Int, Int) => Int = (a, b) => a + b
    // val funcB3: (Int, Int) => Int = a, b => a + b ⇒コンパイルエラー
    val funcB4: (Int, Int) => Int = _ + _
    // val funcB5: (Int, Int) => Int = _ ⇒コンパイルエラー

まとめると・・・

  • 型が推論できる
  • パラメータを順番通りにすべて使う

とき、「_」で代用できる( ..)φメモメモ

  1. 全体としての「_」
  • パラメータリスト全体の場合
    def funcC1(a: Int, b: Int, c: Int) = a + b + c
    val funcC2 = funcC1 _  //⇒funcC2.apply(a, b, c)と同じ意味
    val funcC3: (String) => Unit = println _
    val funcC4: (String) => Unit = println
    // val funcC5: (String, String) => Unit = println ⇒コンパイルエラー

引数が1個の時は「_」自体も省略できる。

  • パラメータリストの部分の場合
    val funcD1 = (a: Int, b: Int, c: Int) => a + b + c
    val funcD2 = funcD1(1, _: Int, 3)

以上(*´ω`*)

Androidをgroovyで作る

groovy2.4から正式にAndroidをサポートしたようで\(^o^)/

AndroidStudioでgroovy開発ができるように設定していみる。

環境(2014/9/7現在)

プロジェクトのbuild.gradle

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.12.2'
        classpath "me.champeau.gradle:gradle-groovy-android-plugin:0.3.0"
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

appのbuild.gradle

apply plugin: 'android'
apply plugin: 'me.champeau.gradle.groovy-android'

android {
    compileSdkVersion 20
    buildToolsVersion "20.0.0"

    defaultConfig {
        applicationId "jp.co.hello.hello_groovy"
        minSdkVersion 17
        targetSdkVersion 20
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/groovy-release-info.properties'
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'org.codehaus.groovy:groovy:2.4.0-beta-3:grooid'
    compile ('org.codehaus.groovy:groovy-json:2.4.0-beta-3') {
        transitive = false
    }
}

repositories {
    jcenter()
}

これからAndroidアプリを作りまくるぞ〜(*´ω`*)

久々の更新・・・(´・ω・`)

scalaのクラス、補助コンストラクタのまとめ

/**
 * コンストラクタのテスト.
 */
object Construct {
  def main(args: Array[String]) {
    // エラー
    //val a1 = new A
    //assert(a1.a == 1)

    val a2 = new A(2)
    assert(a2.a == 2)

    val b1 = new B
    assert(b1.a == 1)

    val c1 = new C
    assert(c1.a == 1 && c1.b == 2)

    val c2 = new C(3)
    assert(c2.a == 3 && c2.b == 2)

    val c3 = new C(4,5)
    assert(c3.a == 4 && c3.b == 5)

    val d1 = new D
    assert(d1.a == 1)

    val d2 = new D(2)
    assert(d2.a == 2)
  }
}

/** 通常クラス. */
class A(_a: Int) {
  val a = _a
}

/** コンストラクタで変数も定義. */
class B(val a: Int) {
  // 補助コンストラクタ
  def this() = this(1)
}

/** 補助コンストラクタ. */
class C(val a: Int, val b : Int) {
  // 引数なし補助コンストラクタ
  def this() = this(1, 2)
  // 引数1つ補助コンストラクタ
  def this(aa: Int) = this(aa, 2)
}

/** デフォルト値. */
class D(val a: Int = 1)

引き続きjava8でも(´・ω・`)
java8で導入されたOptionalをちょっと試す。

public class Sample {
    public static void main(String[] args) {
        // 値が設定されているオプショナル
        Optional<String> o = Optional.of("test");
        // 値取得の場合は、nullチェックが必要
        if (o.isPresent()) {
            System.out.println(o.get());
        }
        // クロージャで
        o.ifPresent(s -> System.out.println(s));

        // 空のオプショナル
        Optional<Object> empty = Optional.empty();
        // デフォルト値
        System.out.println(empty.orElse("デフォルト"));
        // クロージャで
        System.out.println(empty.orElseGet(() -> "デフォルト"));
        try {
            // 例外をthrow
            System.out.println(empty.orElseThrow(() -> new Exception("例外")));
        } catch (Exception ex) {
            Logger.getLogger(Sample.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        // モナド
        Optional.ofNullable("java").map(st -> st.toUpperCase()).ifPresent(st -> System.out.println("s:" + st));
        String res = Optional.ofNullable((String) null).map(st -> st.toUpperCase()).orElse("s:null");
        System.out.println(res);
    }
}

java8で追加されたjava.util.functionパッケージ。
事前定義されているclosureを実行してみる。

public class Smaple {
    public static void main(String[] args) {
        // 1つの引数と1つの戻り値
        Function<String, String> function = s -> "hello world";
        System.out.println(function.apply(""));
        // 1つの引数とbooleanの戻り値
        Predicate<String> predicate = s -> true;
        System.out.println(predicate.test(""));
        // 1つの引数と戻り値なし
        Consumer<String> consumer = s -> System.out.println("hello world");
        consumer.accept("");
        // 引数なしと1つの戻り値
        Supplier<String> supplier = () -> "hello world";
        System.out.println(supplier.get());
        // 2つの引数と1つの戻り値
        BinaryOperator<String> binaryOperator = (s1, s2) -> "hello world";
        System.out.println(binaryOperator.apply("", ""));
        // 独自定義
        MyFunction myFunction = (a,b,c) -> System.out.println("hello world");
        myFunction.apply("", 0, "");
    }
    
    @FunctionalInterface
    interface MyFunction {
        void apply(String a, Integer b, Object c);
    }
}