ScalaでAndroidアプリ開発

14,348 views

Published on

ScalaでAndroidアプリ開発

  1. 1. Scalaで Androidアプリ開発 papamitra / ScalaZa01
  2. 2. 自己紹介 ● Twitter ID: papamitra ● Web: http://d.hatena.ne.jp/papamitra/ ● 名古屋Scala勉強会/第7回から参加 ● Scala歴: 6ヶ月 ● Android歴: 7ヶ月 ● Java歴: ほぼなし
  3. 3. 最初は別の言語で開発していたが… とあるLispのJVM言語
  4. 4. 途中でScalaに乗り換えた
  5. 5. Scalaで開発するメリットって?
  6. 6. Androidアプリが動くまで ソースコード ↓ .classファイル ↓ .dexファイル ↓ .apkファイル ↓ インストール、実行
  7. 7. メソッド名を間違えた (動的言語の場合) インストールまで完了して いざ、実行 ↓ NoSuchMethodException (そんなメソッドないよ)
  8. 8. メソッド名を間違えた (Scalaの場合) コンパイラが指摘 /src/main/scala/CameraService.scala:47: value comprress is not a member of android.graphics.Bitmap bitmap.comprress(Bitmap.CompressFormat.JPEG, 90, outStream) ^ one error found
  9. 9. Scalaならコンパイラが強力に エラーチェック ソースコード ↓ ←Scalaはここで多くのエラーを補足 .classファイル ↓ .dexファイル ↓ .apkファイル ↓ インストール、実行 ←ここで例外が起きるのは悲しい
  10. 10. Scalaなら 実行時エラーが少なくて済む!
  11. 11. 型チェックなら Javaにもあるけど… Scalaならコードが 簡潔に書ける!
  12. 12. Javaのコード例 (OnClickListener) Button button = (Button)findViewById(R.id.Button01); button.setOnClickListener(new OnClickListener{ public void OnClick(View v){ // クリック処理 } })
  13. 13. Scalaのコード例 (OnClickListener) findView(TR.Button01).setOnClickListener( () => { // クリック処理 }) こんなに簡単に!
  14. 14. Scalaのコード例 (OnClickListener) 暗黙の型変換を使用 implicit def funcToClicker0(f:() => Unit):OnClickListener = new OnClickListener() {def onClick(v:View):Unit=f.apply} http://www.ibm.com/developerworks/jp/opensource/library/os-eclipse-scala/
  15. 15. Javaのコード例 (Cursor) public static void useAlarms() { Cursor cur = getAlarmsCursor(); if (cur.moveToFirst()) { do{ Alarm alarm = new Alarm(cur); // alarmを使うコード }while(cur.moveToNext()); } cur.close(); }
  16. 16. Scalaのコード例 (Cursor) def useAlarms(){ using(getAlarmsCursor()){c=> c.map(new Alarm(_)).foreach(alarm=>{ // alarmを使ったコード })}}
  17. 17. Scalaのコード例 (Cursor) def using[A <: {def close(): Unit}, B](param:A)(f: A=>B):B= try{ f(param) }finally{ param.close() } 『Scalaプログラミング入門』より
  18. 18. Scalaのコード例 (Cursor) def useAlarms(){ using(getAlarmsCursor()){c=> c.map(new Alarm(_)).foreach(alarm=>{ // alarmを使ったコード })}}
  19. 19. Scalaのコード例 (Cursor) private object EmptyCursorIter extends Iterator[Cursor]{ def hasNext = false def next:Cursor = throw new java.util.NoSuchElementException() } private class CursorIter(cur: Cursor) extends Iterator[Cursor]{ def hasNext = !cur.isLast() def next:Cursor = if (cur.moveToNext) cur else throw new java.util.NoSuchElementException() } implicit def cursor2Iterator(cur: Cursor): Iterator[Cursor] = if(!cur.moveToFirst) EmptyCursorIter else{ cur.moveToPrevious new CursorIter(cur) }
  20. 20. Scalaなら簡潔で わかり易いコードが書ける!
  21. 21. その一方 Javaっぽく書くこともできる
  22. 22. JavaのHelloアプリ package org.example.hello; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class HelloAndroid extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText("Hello,Android"); setContentView(tv); } }
  23. 23. ScalaのHelloアプリ package org.example.helloscala import android.app.Activity import android.os.Bundle import android.widget.TextView class HelloAndroid extends Activity { override def onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) val tv = new TextView(this) tv.setText("Hello Android, it's me, Scala!") setContentView(tv) } }
  24. 24. ちなみにClojureのHelloアプリ (ns org.example.hello.HelloAndroid (:gen-class :extends android.app.Activity :exposes-methods {onCreate superOnCreate})) (defn -onCreate [this #^android.os.Bundle bundle] (.superOnCreate this bundle) (let [tv (new android.widget.TextView this)] (.setText tv "Hello Android from Clojure!") (.setContentView this tv)))
  25. 25. Scalaで開発するメリット まとめ ● とりあえずJavaっぽく書いて動かせるので AndroidとScala、両方初心者でも安心 ● Scalaに慣れてくればその機能でわかり易く 簡潔なコードが記述可能 ● しかもコンパイラの強力な型チェックで 実行時のエラーを低減
  26. 26. デメリットはないの?
  27. 27. アプリサイズが大きく… コードサイズ apkサイズ Hello,World - 13KB Proguardを使っているものの… 1画面 同機能のJava実装と 1サービス 24KB 111KB 比較して4〜5倍(主観) 1ウィジェット 82KB 215KB 3画面 2サービス Android2.2からはSDカードにアプリをインストールできる →それほど気にならなくなる?
  28. 28. protected staticにアクセス不可 Scalaの仕様で protected staticクラス/メソッド/フィールドにアクセス不可 Androidでは com.google.android.maps.ItemizedOverlay を継承して使うときに問題が… 現状Javaでラッパを書くしか手がない? →ItemizedOverlayにはラッパがあります  http://github.com/brianhsu/ScalaMap
  29. 29. Google Maps API(maps.jar) 使用でコンパイルエラー error: error while loading MapView, Missing dependency     'class android.view.ViewGroup$LayoutParams' android.jar,maps.jarはいずれも 実装が全て例外スローに 置き換えられたスタブ Rev22630にてコンパイルできるように修正されたようです 次期バージョン(2.8.1?)に期待
  30. 30. Google Maps API(maps.jar) でコンパイルエラー Q. 2.8.0以前のバージョンではどうすればよい? A. maps.jarを改変して回避する力技を公開しています http://d.hatena.ne.jp/papamitra/20100627/scala_maps
  31. 31. Scalaで開発するデメリット まとめ いろいろあるけどなんとかなるよ!
  32. 32. Let's Scala + Android !
  33. 33. おまけ もうちょっとだけ続くんじゃ
  34. 34. 私のAndroid開発環境 ● sbt + sbt-android-plugin Scala製ビルドツール ● ensime emacs上のScala開発環境 ● Eclipse + Abdroid-plugin xml編集するのに使用
  35. 35. sbt-android-plugin ● Apk作成はもちろん実機/エミューレータへのイ ンストールも面倒見てくれる ● proguardも勝手にかけてくれる ● インストールはファイル1つDLして パス通すだけ http://github.com/jberkel/android-plugin/raw/master/script/create_project
  36. 36. sbt-android-plugin サンプルプロジェクトを作成して実機にインストールするまで $ create_project HelloAndroid org.papamitra.helloandroid --platform android-2.1 --scala-version 2.8.0 --activity HelloAndroid $ cd HelloAndroid $ sbt update $ sbt install-device
  37. 37. sbt-android-plugin 型付きリソース参照も装備! val button = findViewById(R.id.button).asInstanceOf[Button] val button = findView(TR.button)
  38. 38. ensime ● Emacs上のScala開発環境 ● 補完してくれたり ● クラスの詳細を表示したり ● Flymakeっぽいこともしてくれる ● http://github.com/aemoncannon/ensime
  39. 39. ensime ● 補完
  40. 40. ensime ● クラス詳細
  41. 41. ensime ● flymake
  42. 42. まとめ
  43. 43. まとめ ご自分に合ったツールをお使いください
  44. 44. おわり

×