Androidのプログラミングを簡単にする

226 views
Skip to first unread message

fujio maruyama

unread,
Aug 6, 2011, 9:31:18 PM8/6/11
to 日本Androidの会
丸山です。

先日、友人の浅海さん @asami224 から、Androidの開発を簡単にする、いろいろな手法が
提案されているという話を聞きました。問題意識はあったのですが、具体的な動きは、全く、
チェックしていませんでした。

面白そうな話題なので、簡単に、どんな取り組みなのか紹介したいと思います。
既に、知っている人は、ごめんなさい。

Androidのプログラムでは、次のようなコードを、沢山書きます。

name = (TextView) findViewById(R.id.name);
thumbnail = (ImageView) findViewById(R.id.thumbnail);
loc = (LocationManager)
getSystemService(Activity.LOCATION_SERVICE);
icon = getResources().getDrawable(R.drawable.icon);
myName = getString(R.string.app_name);

こうしたコードは、Androidでは、お約束の定型的なコードなのですが、少し面倒だと
思ったことありませんか?

よく考えると、変というか、無駄なことがあることがわかります。
というのも、これらのコードは、Rファイルで定義された、あるいは、SystemServiceで
定義されているインスタンスを取得しているのですが、Rファイルは、もともとは、自分で
定義した情報から生成されたものですし、SystemServiceは、もともと決まったものです。
型変換のキャストも、当たり前と言えば、当たり前です。

このあたりは、プログラマが考えて指定しなくても、与えられた情報からコンピュータ自身に
考えて処理してもらうことが出来るはずです。

そこで登場するのが、DI(Dependency Injection)という考え方です。Dependency 従属性
というのは、プログラムの中のあるインスタンスは、任意のものでは無くて、他のものによって
(従属して)、性質が決まっていることがあると言うことです。この例の場合では、Rファイルに
従属して、いくつかのインスタンスの性質は決まっています。

Dependency Injection というのは、こうした従属性を持つインスタンスをプログラムの中で
利用する際に、インスタンスの生成の時点で、こうした性質を持つインスタンスを作って
プログラムに、「注入(Injection)」しようというものです。

こうした手法を使うと、次のようなAndroidプログラムは、とても簡単になります。

class AndroidWay extends Activity {
TextView name;
ImageView thumbnail;
LocationManager loc;
Drawable icon;
String myName;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
name = (TextView) findViewById(R.id.name);
thumbnail = (ImageView) findViewById(R.id.thumbnail);
loc = (LocationManager)
getSystemService(Activity.LOCATION_SERVICE);
icon = getResources().getDrawable(R.drawable.icon);
myName = getString(R.string.app_name);
name.setText( "Hello, " + myName );
}
}

これは、こうなります。

class RoboWay extends RoboActivity {
@InjectView(R.id.name) TextView name;
@InjectView(R.id.thumbnail) ImageView thumbnail;
@InjectResource(R.drawable.icon) Drawable icon;
@InjectResource(R.string.app_name) String myName;
@Inject LocationManager loc;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
name.setText( "Hello, " + myName );
}
}

こちらの方が、すっきりしていませんか?

このサンプルは、RoboGuiceというプロジェクトから取ったものです。
http://code.google.com/p/roboguice/wiki/SimpleExample?tm=6
(残念ながら、プロジェクトが整備中なのか、サンプルのソースを見ようとすると、
404が出てしまいますが。)

@InjectView(R.id.name) TextView name;
が、nameというインスタンスを、プログラムに「注入」しているところで、
name = (TextView) findViewById(R.id.name);
の代わりの役割を果たしています。以下、同様です。

@で始まる文字列は、Javaでは、Annotationと言われるものです。
Annotationを自分で作るのは、少し面倒ですが、Annotationを使うのは
とても簡単です。6年前のものですが、「Annotationプログラミング入門」
http://marulec.cloud-market.jp/archive/2004/20050309/annotation_2.pdf

プログラムを簡単にして、開発を容易にしようという取り組みを、EoD
(Ease of Development)と言います。AnnotationやDIは、EoDの有力な
手法です。エンタープライズの世界では、EoDの手法は広く普及しています。
SpringやSeasar2を使ったことがある人は、よくご存じだと思います。

これから、Androidの世界で、プログラミングを簡単にする新しい手法が
(本当は、新しくはないのですが)、どんどん広まっていくと思います。

AndroidでのDI利用のプロジェクト
Roboguice  http://code.google.com/p/roboguice/

RoboguiceのTestでの応用
thorikawaさんのblog http://d.hatena.ne.jp/thorikawa/20101127/p1
@vvakameさんの日記 http://d.hatena.ne.jp/vvakame/20100901/1283354793
esmasuiさんのblog http://d.hatena.ne.jp/esmasui/20100904/1283617914

浅海さんのAndroidプログラム自動生成プロジェクト goldenport-android-library
https://github.com/asami/goldenport-android-library

terumi sakaue

unread,
Aug 6, 2011, 10:22:26 PM8/6/11
to android-g...@googlegroups.com
丸山様
こんにちは、坂上と申します。

Java自体は、Androidアプリを作って初めてやりました。
まず最初に思ったのが、この問題でした。
書くのがめんどくさいって事でした。

色々錯誤して、あっているかどうかはわかりませんが。。。
最近はこんな感じにしています。

/* 共通オブジェクト */
public class CommonObjects {

private static CommonObjects instance = new CommonObjects();
private CommonObjects(){}
public static CommonObjects getInstance() {
return instance;
}

/*
* 共通関数
*/
private View getView(Activity objAct){
return objAct.getWindow().getDecorView();
}

/*
* テキストビュー関連
*/
public void setTextView(Activity objThis, int intTextRID, String
strView){
this.setTextView(getView(objThis), intTextRID, strView);
}
public void setTextView(View objView, int intTextRID, String strView){
TextView txtItem = (TextView)objView.findViewById(intTextRID);
txtItem.setText(strView);
}

public String getTextView(Activity objThis, int intTextRID){
return this.getTextView(getView(objThis), intTextRID);
}
public String getTextView(View objView, int intTextRID){
TextView txtItem = (TextView)objView.findViewById(intTextRID);
return txtItem.getText().toString();
}

}

class AndroidWay extends Activity {

static CommonObjects mclsUser; //共通クラス定義

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// 共通クラス初期化
mclsUser = CommonObjects.getInstance();

// 書き込み
mclsUser.Object().setTextView(this, R.id.name, "Hello");

}
}


この書き方に問題があるのか、もしかしたらおかしい事をやってるんじゃないか
と思いながらも使っています。
こんどは、DIを混ぜて作って見たいと思います。

TAO Seiichiroh

unread,
Aug 7, 2011, 9:26:13 AM8/7/11
to android-g...@googlegroups.com
峠です

Dependency Injection いいですね。判りきった定型文を書くのって無駄に苦痛なんで
こういったプロジェクトには大いに期待するところです

ところで jdk7 あたりに project coin ってのがあって
それは色々な特徴があるんですけど、例えば
Map<String,String> map=new HashMap<String,String>();
って書いてたのが
Map<String,String> map=new HashMap<>();
で OK になります

android (dalvik) の jdk7 対応が待ち遠しいところです


--
// TAO Seiichiroh

Reply all
Reply to author
Forward
0 new messages