2011年7月18日月曜日

Androidのコンテキストについて

Androidにはコンテキストが多々出てくる。

ややこしいため、調べたことを記載。

コンテキストとは、アプリ環境のグローバルな情報へのインタフェース。

Contextクラスを利用して
アプリケーションのリソース、クラス、
アプリケーションレベルのオペレーション(アクティビティの起動、ブロードキャスト、インテントの受信など)
にアクセスすることができる。

現在のアプリやオブジェクトの状態取得できる窓口であるが、以下の3種類で取得できる。

・Activityクラスのthis (アクティビティ・コンテキスト)
・getApplicationContext() (アプリ・コンテキスト)
・getBaseContext() (ベース・コンテキスト)

(注1:ベース・コンテキストは、公式な名称ではなく、勝手に命名してます。)
(注2:サービスクラスのthisは、何コンテキストと言うのか不明)

アクティビティやサービスのthisは、
アプリコンテキストとベースコンテキストの参照を持っていることを確認。

(※参照を持っているだけで、アクティビティ・コンテキストが、
 アプリ・コンテキストやベース・コンテキストを生成しているとは考えにくい)

なお、アクティビティやサービスは、Contextクラスを継承しているため、thisやContextメソッドが使用できる。

ところが、googleエンジニアの一人は、ベース・コンテキスト(getBaseContext)は使用しないで、と言っている。
(今まで、getBaseContext使っているところは、見直す必要がありそうだ)

アプリ・コンテキストおよび、アクティビティ・コンテキストのライフサイクルは、
アプリはアプリ、アクティビティはアクティビティのライフサイクルに依存する。

サービスの登録と解除に関しては、アクティビティ・コンテキストで登録したものは、
アクティビティ破棄時に、開発者がサービス解除を忘れても、フレームワークが解除するとのこと。
ただし、アプリ・コンテキストの場合は、解除わすれるとメモリリークになるとのこと。

2011年7月15日金曜日

定期的にIntentServiceを起動する

IntentServiceは、
Activityからの呼び出し時にAlarmManagerと併用することにより、
定期的な呼び出しを行うことができる。

AlarmManagerは、引数にPendingIntentを要求するため、
PendingIntentを取得する必要がある。
ただ、特に細かい設定はなく、サービスのIntentを型変換しているような感じだ。


■定期的に動くIntentServiceを作る(AlarmManaerを利用)
1)新規のAndroidプロジェクトを以下のように作成する。
「プロジェクト名」:AlarmManagerIntentService
「ビルドターゲット」:Android 1.6
「パッケージ名」:jp.co.example.alarmmanagerintentservice
「アクティビティ名」:AlarmManagerIntentServiceActivity

2)サービスクラスを作成する。
プロジェクトのsrcのパッケージ配下に、『MyIntentService』クラスを作成
ソース内容は以下の通り。

基本的には、MyIntentServiceクラスをIntentServiceクラスの継承クラスとする。
Seriviceの継承とは異なり、コンストラクターのみ強制オーバーライドであった。

Eclipseのコードアシスタントでは、第一引数ありのコンストラクタを生成してくれる、
しかし、
ActivityからAlarmManagerを利用して呼ぶ場合、引数なしのコンストラクタが必要である。

onHandleIntentメソッドには、ログを入れた。
これは、onHandleIntentがどのスレッドで動くか調べるためだ。
結果、onHandleIntentは、時間毎に新規スレッドが生まれる形で動作した。

以下のコードにおけるIntentServiceは、
Activityと同プロセスだが、別スレッドで動作している。

package jp.co.example.alarmmanagerintentservice;

import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

public class MyIntentService extends IntentService {

 private final String TAG = this.getClass().getSimpleName();

 public MyIntentService(String name) {
  super(name);
  // TODO 自動生成されたコンストラクター・スタブ
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 public MyIntentService() {
  super("MyIntentService");
  // TODO 自動生成されたコンストラクター・スタブ
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 protected void onHandleIntent(Intent intent) {
  // TODO 自動生成されたメソッド・スタブ
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());

 }

}

3)画面にスタートボタン、ストップボタンを作る
res\layout\main.xmlに、ボタンを2つ作成。
ソースは以下のようになる。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <Button android:text="Alarm Start" android:id="@+id/start_button" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
    <Button android:text="Alarm Stop" android:id="@+id/stop_button" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
</LinearLayout>


4)サービスをスタート/ストップするアクティビティを作る
以下の処理を行っている。
スタートボタン押下処理をstartAlarmServiceメソッドとした。
ストップボタン押下処理をstopAlarmServiceメソッドとした。
詳細は、ソースコードコメントに記載する。

全体のコードは以下の通り。
package jp.co.example.alarmmanagerintentservice;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class AlarmManagerIntentServiceActivity extends Activity {

 private final String TAG = this.getClass().getSimpleName();

 Button alarmStartButton;
 Button alarmStopButton;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
        setContentView(R.layout.main);

        findViews();

        alarmStartButton.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    // TODO 自動生成されたメソッド・スタブ
    startAlarmService();
   }
  });

        alarmStopButton.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    // TODO 自動生成されたメソッド・スタブ
    stopAlarmService();
   }
  });
    }

    protected void findViews() {
     alarmStartButton = (Button)findViewById(R.id.start_button);
     alarmStopButton = (Button)findViewById(R.id.stop_button);
    }

    protected void startAlarmService() {
     Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
     Context context = getBaseContext();
     // サービスのIntentを生成
     Intent intent = new Intent(context, MyIntentService.class);
     // PendingIntentを取得
     PendingIntent pendingIntent = PendingIntent.getService(
       context,
       -1,  // requestCode is currently not used
       intent, // 起動するサービスのIntent
       PendingIntent.FLAG_UPDATE_CURRENT
        //flags: FLAG_CANCEL_CURRENT :過去の設定をキャンセルし現在の設定を使う。
        //   FLAG_NO_CREATE  :存在してなければnullを返す。新規作成しない。
        //   FLAG_ONE_SHOT  :一度だけ使用できる。
        //   FLAG_UPDATE_CURRENT :過去の設定があればそれを使う。再設定しない。
       );
     AlarmManager alarmManager = (AlarmManager)context.getSystemService(ALARM_SERVICE);
     alarmManager.setInexactRepeating(
       AlarmManager.RTC,
        // type:
        // ELAPSED_REALTIME  :SystemClock.elapsedRealtime() によるアラーム時間 (スリープを含む起動してからの時間)
        // ELAPSED_REALTIME_WAKEUP :ELAPSED_REALTIME と同様だが、スリープしている時は起きる
        // INTERVAL_DAY   :一日間隔
        // INTERVAL_FIFTEEN_MINUTES:15分間隔
        // INTERVAL_HALF_DAY  :半日間隔
        // INTERVAL_HALF_HOUR  :30分間隔
        // INTERVAL_HOUR   :一時間間隔
        // RTC      :System.currentTimeMillis() によるアラーム時間 (UTC)
        // RTC_WAKEUP    :RTC と同様だが、スリープしている時は起きる
       System.currentTimeMillis(), // triggerAtTime
       5000,      // interval
       pendingIntent    // operation
       );
    }

    protected void stopAlarmService() {
     Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
     Context context = getBaseContext();
     // サービスのIntentを生成
     Intent intent = new Intent(context, MyIntentService.class);
     // PendingIntentを取得
     PendingIntent pendingIntent = PendingIntent.getService(
       context,
       -1,  // requestCode is currently not used
       intent,
       PendingIntent.FLAG_UPDATE_CURRENT
       );
     AlarmManager alarmManager = (AlarmManager)context.getSystemService(ALARM_SERVICE);
     alarmManager.cancel(pendingIntent);
    }

}

5)マニフェストでサービス許可する
AndroidManifest.xmlに<service>タグにサービスクラス名を指定して、以下のようにサービスを許可する。
<application android:icon="@drawable/icon" android:label="@string/app_name">
 (略)
 <service android:name=".MyIntentService"/>
</application>

別スレッドで動くIntentService(後始末が自動的)

Androidにはサービスという、Linux等でいうデーモンのような仕組みがある。
何もしないシンプルなサービスでは、Serviceクラスを継承した。
今回は、IntentServiceクラスを継承する。

2つの違いは、以下の通り。
・IntentServiceのonHandleIntentメソッドが、別スレッドで実行される(非同期)
非同期の関連キーワード:AsyncTask、Thread、Runnable
・IntentServiceは、処理が終わると、自動的にonDestroyメソッドが呼ばれサービスが停止すること。

■別スレッドで動くIntentServiceを作る
1)新規のAndroidプロジェクトを以下のように作成する。
「プロジェクト名」:IntentServiceTest0
「ビルドターゲット」:Android 1.6
「パッケージ名」:jp.co.example.intentservicetest0
「アクティビティ名」:IntentServiceTest0Activity

2)サービスクラスを作成する。
プロジェクトのsrcのパッケージ配下に、『MyIntentService』クラスを作成
ソース内容は以下の通り。

基本的には、MyIntentServiceクラスをIntentServiceクラスの継承クラスとする。
Seriviceの継承とは異なり、コンストラクターのみ強制オーバーライドであった。

Eclipseのコードアシスタントでは、第一引数ありのコンストラクタを生成してくれる、
しかし、
Activityで以下のコードでサービスを起動するには、
引数なしのコンストラクタが必要となることに注意。
startService(new Intent(getBaseContext(), MyIntentService.class));

onBind、onCreate、onDestroy、onStartは、オーバーライドは任意。
今回はログ確認用に、オーバーライドしている。

また、別スレッドで動くonHandleIntentメソッドには、スリープを5秒間入れた。
これは、onHandleIntentがどのスレッドで動くか調べるためだ。
結果、onHandleIntentは、新規スレッドで動作した。

つまりは、以下のコードにおけるIntentServiceは、
Activityと同プロセスだが、別スレッドで動作している。

package jp.co.example.intentservicetest0;

import android.app.IntentService;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MyIntentService extends IntentService{

 private final String TAG = this.getClass().getSimpleName();

 public MyIntentService(String name) {
  super(name);
  // TODO 自動生成されたコンストラクター・スタブ
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 public MyIntentService() {
  super("MyIntentService");
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 protected void onHandleIntent(Intent arg0) {
  // TODO 自動生成されたメソッド・スタブ
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
  try {
   Thread.sleep(5000);
  } catch (InterruptedException e) {
   // TODO 自動生成された catch ブロック
   e.printStackTrace();
  }
 }

 @Override
 public IBinder onBind(Intent intent) {
  // TODO 自動生成されたメソッド・スタブ
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
  return super.onBind(intent);
 }

 @Override
 public void onCreate() {
  // TODO 自動生成されたメソッド・スタブ
  super.onCreate();
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 public void onDestroy() {
  // TODO 自動生成されたメソッド・スタブ
  super.onDestroy();
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 public void onStart(Intent intent, int startId) {
  // TODO 自動生成されたメソッド・スタブ
  super.onStart(intent, startId);
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

}

3)画面にスタートボタン、ストップボタンを作る
res\layout\main.xmlに、ボタンを2つ作成。
ソースは以下のようになる。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <Button android:text="Start" android:id="@+id/start_button" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
    <Button android:text="Stop" android:id="@+id/stop_button" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>

</LinearLayout>


4)サービスをスタート/ストップするアクティビティを作る
以下の処理を行っている。
スタートボタン押下で次を実行。
startService(new Intent(getBaseContext(), MyIntentService.class));
ストップボタン押下で次を実行。
stopService(new Intent(getBaseContext(), MyIntentService.class));

全体のコードは以下の通り。
package jp.co.example.intentservicetest0;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class IntentServiceTest0Activity extends Activity {
 Button startButton;
 Button stopButton;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        findViews();

        startButton.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    // TODO 自動生成されたメソッド・スタブ
    startService(new Intent(getBaseContext(), MyIntentService.class));
   }
  });

        stopButton.setOnClickListener(new OnClickListener() {

     public void onClick(View v) {
      // TODO 自動生成されたメソッド・スタブ
      stopService(new Intent(getBaseContext(), MyIntentService.class));
     }
    });
    }

    protected void findViews() {
     startButton = (Button)findViewById(R.id.start_button);
     stopButton = (Button)findViewById(R.id.stop_button);
    }
}

5)マニフェストでサービス許可する
AndroidManifest.xmlにタグにサービスクラス名を指定して、以下のようにサービスを許可する。


<application android:icon="@drawable/icon" android:label="@string/app_name">
 (略)
 <service android:name=".MyIntentService"/>
</application>

2011年7月14日木曜日

簡単なソースでサービスを調べる

Androidにはサービスという、Linux等でいうデーモンのような仕組みがある。
一口にサービスといっても、色々なコーディング方法がある。

まずは、何もしないサービスをActivityから呼び出して、調査しよう。


■何もしないサービスを作る
1)新規のAndroidプロジェクトを以下のように作成する。
「プロジェクト名」:ServiceTest0
「ビルドターゲット」:Android 1.6
「パッケージ名」:jp.co.example.servicetest0
「アクティビティ名」:ServiceTest0Activity

2)サービスクラスを作成する。
プロジェクトのsrcのパッケージ配下に、『MyService』クラスを作成
ソース内容は以下の通り。

基本的には、MyServiceクラスをServiceクラスの継承クラスとし、
onBindメソッドは、親のServiceクラスでabstractなので、強制的にオーバーライド。
onCreate、onDestroy、onStartは、オーバーライドは任意。
だが、何か処理をするためのサービスなので、通常はオーバーライド必須だろう。
各メソッドには、ログを埋め込んだ。

また、onStartメソッドには、スリープを5秒間入れた。
これは、onStartがどのスレッドで動くか調べるためだ。
結果、onStartは、Activityと同じmainスレッドで動作した。

つまりは、以下のコードにおけるサービスとは、
Activityと別プロセスどころか、別スレッドでもない。
(注:別プロセスで動くサービスもちゃんと用意されている)

package jp.co.example.servicetest0;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service{

 private final String TAG = this.getClass().getSimpleName();

 @Override
 public IBinder onBind(Intent arg0) {
  // TODO 自動生成されたメソッド・スタブ
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
  return null;
 }

 @Override
 public void onCreate() {
  // TODO 自動生成されたメソッド・スタブ
  super.onCreate();
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 public void onDestroy() {
  // TODO 自動生成されたメソッド・スタブ
  super.onDestroy();
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 public void onStart(Intent intent, int startId) {
  // TODO 自動生成されたメソッド・スタブ
  super.onStart(intent, startId);
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());

  Log.d(TAG, "sleep start");
  try {
   Thread.sleep(5000);
  } catch (InterruptedException e) {
   // TODO 自動生成された catch ブロック
   e.printStackTrace();
  }
  Log.d(TAG, "sleep end");
 }

}
3)画面にスタートボタン、ストップボタンを作る
res\layout\main.xmlに、ボタンを2つ作成。
ソースは以下のようになる。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <Button android:text="Start" android:id="@+id/start_button" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
    <Button android:text="Stop" android:id="@+id/stop_button" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
</LinearLayout>


4)サービスをスタート/ストップするアクティビティを作る
以下の処理を行っている。
スタートボタン押下で次を実行。
startService(new Intent(getBaseContext(), MyService.class));
ストップボタン押下で次を実行。
stopService(new Intent(getBaseContext(), MyService.class));

全体のコードは以下の通り。
package jp.co.example.servicetest0;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ServiceTest0Activity extends Activity {

 Button startButton;
 Button stopButton;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        findViews();

        startButton.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    // TODO 自動生成されたメソッド・スタブ
    startService(new Intent(getBaseContext(), MyService.class));
   }
  });

        stopButton.setOnClickListener(new OnClickListener() {

     public void onClick(View v) {
      // TODO 自動生成されたメソッド・スタブ
      stopService(new Intent(getBaseContext(), MyService.class));
     }
    });
    }

    protected void findViews() {
     startButton = (Button)findViewById(R.id.start_button);
     stopButton = (Button)findViewById(R.id.stop_button);
    }
}

5)マニフェストでサービス許可する
AndroidManifest.xmlにタグにサービスクラス名を指定して、以下のようにサービスを許可する。

<application android:icon="@drawable/icon" android:label="@string/app_name">
 (略)
 <service android:name=".MyService"/>
</application>

2011年7月13日水曜日

Androidの考え方

■OnDestroyが呼ばれても、プロセスがなくなるとは限らない
ActivityのライフサイクルでOnDestroyが呼ばれても、プロセスは残る。
理由は、プロセス生成の電力コストを下げるため、できるだけ再利用したいからだそうだ。

いつアプリのプロセスは終了するのか。
 LowMemoryKillerというカーネルのドライバがメモリ不足を検知したとき、
使われていないアプリを停止させる。この時である。

開発時に気をつけること、
staticクラス変数は、LowMemoryKillerがプロセスを停止するまで、維持されること。
逆の発想では、LowMemoryKiller次第で、いつでもstaticクラス変数が破棄されること。

プロセスやstaticクラス変数が、処理中に破棄されては困るなら、
サービスとして作成するのがシンプルな方法の一つである。

Activityのライフサイクルを確認する

イベントに対応したActivityのライフサイクは以下の通り。
実機およびエミュレータで確認し、作成。


上記を調査したソースは以下の通り。
メソッドをオーバーライドし、ログを埋め込んだだけのソースです。

package jp.co.example.lifecycle;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class LifeCycleActivity extends Activity {

 private final String TAG = this.getClass().getSimpleName();

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
        setContentView(R.layout.main);
    }

 @Override
 protected void onDestroy() {
  // TODO 自動生成されたメソッド・スタブ
  super.onDestroy();
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 protected void onPause() {
  // TODO 自動生成されたメソッド・スタブ
  super.onPause();
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 protected void onRestart() {
  // TODO 自動生成されたメソッド・スタブ
  super.onRestart();
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 protected void onRestoreInstanceState(Bundle savedInstanceState) {
  // TODO 自動生成されたメソッド・スタブ
  super.onRestoreInstanceState(savedInstanceState);
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 protected void onResume() {
  // TODO 自動生成されたメソッド・スタブ
  super.onResume();
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 protected void onSaveInstanceState(Bundle outState) {
  // TODO 自動生成されたメソッド・スタブ
  super.onSaveInstanceState(outState);
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 protected void onStart() {
  // TODO 自動生成されたメソッド・スタブ
  super.onStart();
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

 @Override
 protected void onStop() {
  // TODO 自動生成されたメソッド・スタブ
  super.onStop();
  Log.d(TAG, Thread.currentThread().getStackTrace()[2].getMethodName());
 }

}

2011年7月11日月曜日

Android開発環境を作成する

Android開発環境を作成する。


■Java Development Kit(JDK)をインストール(本家)
 ・JDKを選択。(キーワード:Windowsが32bitならWindows x86。64bitならWindows x64)
  AndroidSDKには、最新のJDKで動いてもらいましょう。
■AndroidSDKをダウンロード(本家)
 ・パス設定等自動でするexe版が便利。
 ・インストールする。
 ・インストール後、実行するとInstalling Archivesが起動するので、
  All Accept(すべて受諾)を選択し、アーカイブをインストールする。
  (かなり時間かかります(2、3時間?)。
   とりあえず、最低限、必要なバージョンの
   「SDK Platform Android」、「Documentation for Android SDK」で動くとのこと。)
■Eclipse3.7(java ee版)をダウンロード(Pleiades All in One 日本語ディストリビューション)
 ・Java(本家ではJavaEE相当)の(開発環境を固定するため)JREありを選択する。
 ・ダウンロード後、解凍する。
■EclipseへAndroidプラグインをインストール
 ・eclipse.exeを起動する。
 ・メニューの「ヘルプ」→「新規ソフトウェアのインストール」を選択。
 ・「インストール」画面の(右上)「追加」ボタンを押下。
 ・「リボジトリーの追加」画面」に以下を入力する。
   「名前」:『Android Plugin』、
   「ロケーション」:『https://dl-ssl.google.com/android/eclipse/』(※1)
   (※1)エラーが発生する場合は『http://dl-ssl.google.com/android/eclipse/
 ・「開発ツール」というチェックボックスが表示されるのでチェックする。
   (DDMS等、4つにチェックが入るはず)
 ・「次へ」ボタンや、同意を促すラジオボタンを押下していくと、インストールが始まる。
■eclipseの設定をする。
 ・メニューの「ウィンドウ」→「設定」を選択し、「設定」ダイアログを出す。
 ●文字コードの設定(確認)
  ダイアログ左から「一般」→「ワークスペース」を選択。
   「テキスト・ファイルのエンコード」を「UTF-8」とする。
 ●Android SDKのパス設定
  ダイアログ左から「Android」を選択。
   「SDK ロケーション」に先にインストールしたAndroid SDKのパスを入力する。
   「適用」ボタン押下し、「ターゲット名」リストに「Android 2.2」等が表示するのを確認。
 ☆以下、お好みで☆
 ●エディター行番号の表示(Pleiades版ではデフォルトONです)
  ダイアログ左から「一般」→「エディター」→「テキスト・エディター」を選択。
   「行番号の表示」チェックボックスをONにする。
■Eclipseのアップデート
 メニューの「ヘルプ」→「更新の確認」
 (たま~に、Eclipseのバグが目に見えて解消されるので、お勧め。)
■Android Virtual devicesの設定
 今回、EclipseのAndroidプラグインから設定する。
 メニューの「ウィンドウ」→「Android SDK および AVD マネージャー」を選択し
 ダイアログを起動する。
 ダイアログ左から「Virtual devices」を選択。ダイアログ右から「New(新規)」ボタン押下。
 まずは、万人に利用されるであろう、Android 1.6のAVDを作成します。
 「Create new Android Virtual Device (AVD)」画面に以下を設定する。
  ・「Name(名前)」:『Android1.6』
  ・「Target(ターゲット)」:『Android 1.6 - API Level 4』
  ・「SD Card」の「Size(サイズ)」:64M
 あとは、必要に応じてAVDを作成することになります。

■Eclipseの便利なショートカット
 ・インポート宣言の追加 : Ctrl + Shift + M
 ・インポート宣言の編成 : Ctrl + Shift + O
 ・コメントの有効・無効 : Ctrl + /
 ・次を検索 : Ctrl + K
 ・前を検索 : Ctrl + Shift + K
 
 ※注意しなければいけないもの
 ・行削除 : Ctrl + D (保存するとき間違えて押さないよう)

■Androidエミュレータの画面サイズ
 ノートパソコンでAndroidエミュレータを起動すると、およそモニターからはみ出てしまう。
 対処法は2つある。
  方法1:「Android SDK および AVD マネージャー」からADVを起動しておく方法
       ADVを開始する際に表示される「Launch Option」ダイアログで、
       「Screen Size」を『6』とすると、1024*768モニターでは丁度いい。
  方法2:作成済みAndroidプロジェクトの実行構成の追加オプションで指定する方法
       Eclipseの「パッケージ・エクスプローラー」からAndroidプロジェクトを右クリックし、
       「実行」→「実行の構成」を選択し、「実行構成」ダイアログを表示。
       ダイアログ右の「ターゲット」タブを選択し、
       「エミュレーター・コマンド行の追加オプション」へ、『-scale 0.6』を追記する。