More Related Content Similar to ScalaでAndroidアプリ開発 Similar to ScalaでAndroidアプリ開発 (20) ScalaでAndroidアプリ開発2. 自己紹介
● Twitter ID: papamitra
● Web: http://d.hatena.ne.jp/papamitra/
● 名古屋Scala勉強会/第7回から参加
● Scala歴: 6ヶ月
● Android歴: 7ヶ月
● Java歴: ほぼなし
7. メソッド名を間違えた
(動的言語の場合)
インストールまで完了して
いざ、実行
↓
NoSuchMethodException
(そんなメソッドないよ)
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. Scalaならコンパイラが強力に
エラーチェック
ソースコード
↓ ←Scalaはここで多くのエラーを補足
.classファイル
↓
.dexファイル
↓
.apkファイル
↓
インストール、実行 ←ここで例外が起きるのは悲しい
12. Javaのコード例
(OnClickListener)
Button button = (Button)findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener{
public void OnClick(View v){
// クリック処理
}
})
13. Scalaのコード例
(OnClickListener)
findView(TR.Button01).setOnClickListener( () => {
// クリック処理
})
こんなに簡単に!
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. 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. Scalaのコード例
(Cursor)
def useAlarms(){ using(getAlarmsCursor()){c=>
c.map(new Alarm(_)).foreach(alarm=>{
// alarmを使ったコード
})}}
17. Scalaのコード例
(Cursor)
def using[A <: {def close(): Unit}, B](param:A)(f: A=>B):B=
try{
f(param)
}finally{
param.close()
}
『Scalaプログラミング入門』より
18. Scalaのコード例
(Cursor)
def useAlarms(){ using(getAlarmsCursor()){c=>
c.map(new Alarm(_)).foreach(alarm=>{
// alarmを使ったコード
})}}
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)
}
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. Scalaで開発するメリット
まとめ
● とりあえずJavaっぽく書いて動かせるので
AndroidとScala、両方初心者でも安心
● Scalaに慣れてくればその機能でわかり易く
簡潔なコードが記述可能
● しかもコンパイラの強力な型チェックで
実行時のエラーを低減
27. アプリサイズが大きく…
コードサイズ apkサイズ
Hello,World - 13KB
Proguardを使っているものの…
1画面 同機能のJava実装と
1サービス 24KB 111KB 比較して4〜5倍(主観)
1ウィジェット
82KB 215KB
3画面
2サービス
Android2.2からはSDカードにアプリをインストールできる
→それほど気にならなくなる?
28. protected staticにアクセス不可
Scalaの仕様で
protected staticクラス/メソッド/フィールドにアクセス不可
Androidでは
com.google.android.maps.ItemizedOverlay
を継承して使うときに問題が…
現状Javaでラッパを書くしか手がない?
→ItemizedOverlayにはラッパがあります
http://github.com/brianhsu/ScalaMap
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. Google Maps API(maps.jar)
でコンパイルエラー
Q. 2.8.0以前のバージョンではどうすればよい?
A. maps.jarを改変して回避する力技を公開しています
http://d.hatena.ne.jp/papamitra/20100627/scala_maps
34. 私のAndroid開発環境
● sbt + sbt-android-plugin
Scala製ビルドツール
● ensime
emacs上のScala開発環境
● Eclipse + Abdroid-plugin
xml編集するのに使用
35. sbt-android-plugin
● Apk作成はもちろん実機/エミューレータへのイ
ンストールも面倒見てくれる
● proguardも勝手にかけてくれる
● インストールはファイル1つDLして
パス通すだけ
http://github.com/jberkel/android-plugin/raw/master/script/create_project
37. sbt-android-plugin
型付きリソース参照も装備!
val button = findViewById(R.id.button).asInstanceOf[Button]
val button = findView(TR.button)
38. ensime
● Emacs上のScala開発環境
● 補完してくれたり
● クラスの詳細を表示したり
● Flymakeっぽいこともしてくれる
● http://github.com/aemoncannon/ensime
Editor's Notes 40秒 50秒 20秒