androidサービス学習

12916 ワード

Serviceはandroidシステムのコンポーネントで、Activityとのレベル差は多くありませんが、自分では実行できません.バックグラウンドでしか実行できません.また、他のコンポーネントとインタラクティブに使用できます.サービスの起動には、次の2つの方法があります.
context.startService()
および
context.
bindService().
 
使用
context.
startService()サービスを起動すると経験します.
context.startService()  ->onCreate()->onStart()->Service running
context.stopService() | ->onDestroy() ->Service stop
 
 
サービスがまだ実行されていない場合は、androidはonCreate()を呼び出し、onStart()を呼び出します.サービスがすでに実行されている場合、onStart()のみが呼び出されるため、1つのサービスのonStartメソッドが複数回呼び出される場合があります. 
 
stopServiceの場合は直接onDestroy、呼び出し者自身がstopServiceを呼び出さずに直接終了した場合は、サービスはバックグラウンドで実行されます.このサービスの呼び出し元は、再起動するとstopServiceでサービスを閉じることができます.
 
したがって、startServiceを呼び出すライフサイクルは、onCreate-->onStart(複数回呼び出すことができる)-->onDestroyです.
 
使用方法
context
.bindService()サービス起動経験:
context
.bindService()->onCreate()->onBind()
->Service running
onUnbind() ->
onDestroy() ->Service stop
 
onBindはクライアントにIBindインタフェースのインスタンスを返します.IBindは、サービスが実行されている状態や他の操作を得るなど、クライアントがサービスをコールバックする方法を許可します.このとき呼び出し元(Activityなど)はServiceにバインドされ、Contextが終了すると、SreviceはonUnbind->onDestroyを呼び出して終了します.
      
したがってbindServiceを呼び出すライフサイクルは、onCreate-->onBind(1回のみ、複数回バインドできません)-->onUnbind-->onDestoryです.
 
サービスのオン・オフのたびに、onStartのみが複数回呼び出され(複数回startService呼び出しにより)、他のonCreate、onBind、onUnbind、onDestoryは1ライフサイクルで1回しか呼び出されません.
 
サービスはマルチメディアを再生するときにユーザーが他のActivityを起動したときにプログラムをバックグラウンドで再生し続けるなど、SDカード上のファイルの変化を検出したり、バックグラウンドで地理情報の位置の変化を記録したりするなど、多くの場面で使用できます.つまり、サービスはいつも後ろに隠されています.
 
次に、startServiceとbindServiceをそれぞれ使用してローカルサービスを開始する簡単な音楽再生アプリケーションを作成しました.
そして次の『
Androidサービス学習(下)』では、AIDLによるサービスのリモートコールについて説明します.
 
アプリケーション起動インタフェース全体を次に示します.
まずstartServiceを使用してサービスを起動することから始めます
 
 
まずActivityを作成します
public class PlayMusic extends Activity implements OnClickListener {
    private static final String TAG = "PlayMusic";
    private Button playBtn;
    private Button stopBtn;
    private Button pauseBtn;
    private Button exitBtn;
    private Button closeBtn;
 
    //....(    )
 
@Override
    public void onClick(View v) {
        int op = -1;
        Intent intent = new Intent("org.allin.android.musicService");
         
        //   
//      Intent intent = new Intent("org.allin.android.musicReceiver");
         
        switch (v.getId()) {
        case R.id.play:
            Log.d(TAG, "onClick: playing muic");
            op = 1;
            break;
        case R.id.stop:
            Log.d(TAG, "onClick: stoping music");
            op = 2;
            break;
        case R.id.pause:
            Log.d(TAG, "onClick: pausing music");
            op = 3;
            break;
        case R.id.close:
            Log.d(TAG, "onClick: close");
            this.finish();
            break;
        case R.id.exit:
            Log.d(TAG, "onClick: exit");
            op = 4;
            stopService(intent);
            this.finish();
            break;
        }
         
        Bundle bundle  = new Bundle();
        bundle.putInt("op", op);
        intent.putExtras(bundle);
        startService(intent);
         
//      sendBroadcast(intent);
    }
 
 
}

書き換えによる
onClickメソッドは、音楽を再生する制御を実現します.ここでは音楽を再生する様々な操作をデジタルでサービスに伝える. 
Intent、nt intent=new Intent(「org.allin.android.musicService」)を構築します.
「org.allin.android.musicService」はAndroidManifestです.xmlファイルでのサービスクラスの定義
<service android:enabled="true" android:name=".MusicService">
<intent-filter>
<action android:name="org.allin.android.musicService" />
</intent-filter>
</service>

操作コードを置く
Bundleで
 
Bundle bundle  = new Bundle();
bundle.putInt("op", op);
intent.putExtras(bundle);
最後にstartService(intent)を使用します.サービスを開始します.
 
サービスがどのように実現されているかを見てみましょう.
 
MusicService.java
/**
 * @author allin.dev
 * http://allin.cnblogs.com/
 * 
 */
public class MusicService extends Service {
 
    private static final String TAG = "MyService";
    private MediaPlayer mediaPlayer;
 
    /*
     * (non-Javadoc)
     * 
     * @see android.app.Service#onBind(android.content.Intent)
     */
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
 
    @Override
    public void onCreate() {
        Log.v(TAG, "onCreate");
        if (mediaPlayer == null) {
            mediaPlayer = MediaPlayer.create(this, R.raw.tmp);
            mediaPlayer.setLooping(false);
        }
    }
 
    @Override
    public void onDestroy() {
        Log.v(TAG, "onDestroy");
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }
    }
 
    @Override
    public void onStart(Intent intent, int startId) {
        Log.v(TAG, "onStart");
        if (intent != null) {
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
 
                int op = bundle.getInt("op");
                switch (op) {
                case 1:
                    play();
                    break;
                case 2:
                    stop();
                    break;
                case 3:
                    pause();
                    break;
                }
 
            }
        }
 
    }
 
    public void play() {
        if (!mediaPlayer.isPlaying()) {
            mediaPlayer.start();
        }
    }
 
    public void pause() {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
        }
    }
 
    public void stop() {
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            try {
                //    stop         start    ,      prepare  
                mediaPlayer.prepare();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
 
}

サービスはシステム付属品を使用しております
MediaPlayerは音楽の再生制御を行う.startServiceが呼び出されると、サービスは先にonCreateを呼び出し、MediaPlayerを初期化します.次にonStartが呼び出され、
startService()に渡されるIntentオブジェクトはonStart()メソッドに渡され、intent内のオペレーティングコードを得ることができます.
Iundle bundle = intent.getExtras();
 
int op = bundle.getInt("op");
その後、より定義された操作コードを用いて、対応するf再生操作を行う.起動後の画面は次の図の通りです.
 
 
図中の「close」と「exit」は異なり、closeは呼び出しのみ
finish()は現在のActivityを終了しますが、Serviceはオフにされず、コンサートは継続して放送されます.exitはstopService(intent)を呼び出した.サービスを停止すると、サービスはonDestroy()メソッドを呼び出してmediaPlayerのリソースを停止および解放します.
 
サービスがいくつかの操作インタフェースしか提供されていない場合、ブロードキャストg方式でサービスを開始することもできます.
まずReceiverを定義し、BroadcastReceiverを継承し、AndroidManifest.xmlに登録するには:
<receiver android:name=".MusicReceiver">
<intent-filter>
<action android:name="org.allin.android.musicReceiver" />
</intent-filter>
</receiver>

Receiverの実装:
 
MusicReceiver.java
/**
 * @author allin.dev
 * http://allin.cnblogs.com/
 *
 */
public class MusicReceiver extends BroadcastReceiver {
 
    private static final String TAG = "MusicReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive");
        Intent it = new Intent("org.allin.android.musicService");
        Bundle bundle = intent.getExtras();
        it.putExtras(bundle);
         
        if(bundle != null){
            int op = bundle.getInt("op");
            if(op == 4){
                context.stopService(it);
            }else{
                context.startService(it);
            }
        }
         
    }
 
}

そして
PlayMusicのonclickメソッドをいくつか改造し、IntentをReceiverに向ける
Intent intent = new Intent("org.allin.android.musicReceiver");
intentでバインドされたオペレーティングコードは変更されません.
さいよびだし
sendBroadcast(intent);intentgを放送します.

MusicReceiverは、放送を受信した後、操作コードに従って対応する操作を行う.
次の例は
bindServiceでサービスを開始
まず同じように書きます
Activity
public class PlayBindMusic extends Activity implements OnClickListener {
 
    private static final String TAG = "PlayBindMusic";
    private Button playBtn;
    private Button stopBtn;
    private Button pauseBtn;
    private Button exitBtn;
     
    private BindMusicService musicService;
 
    @Override
    public void onClick(View v) {
 
        switch (v.getId()) {
        case R.id.play:
            Log.d(TAG, "onClick: binding srvice");
            musicService.play();
            break;
        case R.id.stop:
            Log.d(TAG, "onClick: stoping srvice");
            if(musicService != null){
                musicService.stop();
            }
            break;
        case R.id.pause:
            Log.d(TAG, "onClick: pausing srvice");
            if(musicService != null){
                musicService.pause();
            }
            break;
        case R.id.exit:
            Log.d(TAG, "onClick: exit");
            this.finish();
            break;
        }
    }
 
 
private void connection(){
        Log.d(TAG, "connecting.....");
        Intent intent = new Intent("org.allin.android.bindService");
        bindService(intent, sc, Context.BIND_AUTO_CREATE);
         
    }
private ServiceConnection sc = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            musicService = null;
            Log.d(TAG, "in onServiceDisconnected");
        }
         
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            musicService = ((BindMusicService.MyBinder)(service)).getService();
            if(musicService != null){
                musicService.play();
            }
             
            Log.d(TAG, "in onServiceConnected");
        }
    };
}

ここではbindService(intent,sc,Context.BIND_AUTO_CREATE)を使用しています.サービスを開始するために、
ServiceConnectionnを定義し、サービスバインドが成功するとServiceConnectionnのコールバック関数が呼び出される方法を実装する必要があります.
public void onServiceConnected(ComponentName name, IBinder service),
コールバック関数にはmusicService=((BindMusicService.MyBinder)(service))が使用されます.getService();BindMusicServiceオブジェクトを取得するには、BindMusicServiceインスタンスオブジェクトがあれば、サービスが提供する様々な音楽再生を制御する機能を呼び出すことができます.
次はBindMusicServicesを見てみましょう.JAvaの実装:
/**
 * @author allin.dev
 * http://allin.cnblogs.com/
 */
public class BindMusicService extends Service {
 
    private static final String TAG = "MyService";
    private MediaPlayer mediaPlayer;
 
    private final IBinder binder = new MyBinder();
 
    public class MyBinder extends Binder {
        BindMusicService getService() {
            return BindMusicService.this;
        }
    }
 
    /*
     * (non-Javadoc)
     * 
     * @see android.app.Service#onBind(android.content.Intent)
     */
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind");
        play();
        return binder;
    }
 
    @Override
    public void onCreate() {
        super.onCreate();
         
        Log.d(TAG, "onCreate");
        Toast.makeText(this, "show media player", Toast.LENGTH_SHORT).show();
         
         
    }
 
    @Override
    public void onDestroy() {
        super.onDestroy();
         
        Log.d(TAG, "onDestroy");
        Toast.makeText(this, "stop media player", Toast.LENGTH_SHORT);
        if(mediaPlayer != null){
            mediaPlayer.stop();
            mediaPlayer.release();
        }
    }
 
     
    public void play() {
        if (mediaPlayer == null) {
            mediaPlayer = MediaPlayer.create(this, R.raw.tmp);
            mediaPlayer.setLooping(false);
        }
        if (!mediaPlayer.isPlaying()) {
            mediaPlayer.start();
        }
    }
 
    public void pause() {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
        }
    }
 
    public void stop() {
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            try {
                //    stop         start    ,      prepare  
                mediaPlayer.prepare();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
 
}

サービスにはIBinderオブジェクトを返すonBindメソッドがあります.このメソッドは、サービスが他のプログラムにバインドされているときに呼び出されます.このIBinderオブジェクトは、前に見たonServiceConnectedメソッドに渡されたIBinderと同じものです.アプリケーションとサービス間ではこのIBinderオブジェクトによる通信が行われる.
起動後の画面は次の図のようになります.
:[ソースダウンロード]
転載先:http://www.cnblogs.com/allin/archive/2010/05/15/1736458.html