关于Android中Service与Activity的信息交互

Android中信息交互大致有两种方式:

1. 使用intent在service和activity之间不停地传递信息

2. 使用bindService实现, 这里有两种实现方式, 在重写service当中的onBind方法是, 一种方式是通过实现一个Binder接口, 通过在这个接口中的实现一个getService方法返回service.this实现, 另一种方法是使用aidl这种接口来实现.

现在截取部分代码:

第一种实现方式

Service中代码

 class MBinder extends Binder {

  MyService getService(){

   

   return MyService.this;

  }

 }

 //切记此处需要进行初始化

 private MBinder mBinder = new MBinder();

 

第二种实现方式

Service中代码:

  public int playMusic() throws android.os.RemoteException {

            Log.i("CHEN","Play music");

            //创建音乐播放器

            if(mp == null) {

             mp = MediaPlayer.create(MyService.this, R.raw.today);

             mp.stop();

             try {

     mp.prepare();

    } catch (IllegalStateException e) {

     // TODO Auto-generated catch block

     e.printStackTrace();

    } catch (IOException e) {

     // TODO Auto-generated catch block

     e.printStackTrace();

    }

             mp.start();

             isStart = true;

             return CREATE;

            } else if(!isStart) {

             mp.stop();

             try {

     mp.prepare();

    } catch (IllegalStateException e) {

     // TODO Auto-generated catch block

     e.printStackTrace();

    } catch (IOException e) {

     // TODO Auto-generated catch block

     e.printStackTrace();

    }

             mp.start();

             isStart = true;

             return START;

            } else if(mp.isPlaying()) {

             mp.pause();

             return PAUSE;

            } else {

             mp.start();

             return PLAY;

            }

           

  }

  public void stopMusic() throws android.os.RemoteException {

            Log.i("CHEN""Stop music"); 

            if(mp.isPlaying()) {

             isStart = false;

             mp.stop();

            }

  }

  

  public int getCondition() throws android.os.RemoteException {

   if(mp == null)

    return UNCREATE;

   else if(!isStart)

    return STOP;

   else if(!mp.isPlaying())

    return PAUSE;

   else

    return PLAY;

  }

 };

 

 @Override

 public IBinder onBind(Intent arg0) {

  // TODO Auto-generated method stub

  Log.v("MyService""Bind");

  return binder;

 }

.aidl接口定义

//切记此处需要指明包名

package android.mp3player;

interface MusicControlService

{

 int playMusic();

 void stopMusic();

 int getCondition();

}

 

在解决了信息交互的问题后, 仍存在一个容易忽视的问题, 你的Service如何被多次创建的activity取得而不是在创建新的service, 也就是说怎么样实现在一个activity被关闭后再次打开仍能够取得你之前创建的service.

这里有一个小技巧.

通过为activity和service中主要方法(onCreate, onStart, bindService, unBindService, reBind等添加log.v()的日志输出命令) 我们可以观察到整个程序的执行顺序:

activityCreate, activityStart, bindService, serviceCreate, serviceStart, activityUnBind, activityStop, activityDestroy.

这个周期中我没有调用startService方法, 而是只是用了bindService方法, 它自动调用了service的Create, Start方法, 也就是说这样会再次创建一个Service.

想要取得之前创建的Service, 达到创建一次, 使用多次的目的, 需要直接调用startActivity方法, 同时重写Service中unbind方法和rebind方法. 这次当activity调用startService方法的时候会自动判断是否存在以创建的Service, 然后调用rebind方法取得这个对象.

粘贴代码如下

Service中

package android.mp3player;

import java.io.IOException;

import android.app.Service;

import android.content.Intent;

import android.media.MediaPlayer;

import android.os.IBinder;

import android.util.Log;

public class MyService extends Service {

 

 public static final int CREATE = 0;

 public static final int START = 1;

 public static final int PAUSE = 2;

 public static final int PLAY = 3;

 public static final int STOP = 4;

 public static final int UNCREATE = 5;

 

 private final MusicControlService.Stub binder = new MusicControlService.Stub()

 {

        MediaPlayer mp;

  boolean isStart;

  

  public int playMusic() throws android.os.RemoteException {

            Log.i("CHEN","Play music");

            //创建音乐播放器

            if(mp == null) {

             mp = MediaPlayer.create(MyService.this, R.raw.today);

             mp.stop();

             try {

     mp.prepare();

    } catch (IllegalStateException e) {

     // TODO Auto-generated catch block

     e.printStackTrace();

    } catch (IOException e) {

     // TODO Auto-generated catch block

     e.printStackTrace();

    }

             mp.start();

             isStart = true;

             return CREATE;

            } else if(!isStart) {

             mp.stop();

             try {

     mp.prepare();

    } catch (IllegalStateException e) {

     // TODO Auto-generated catch block

     e.printStackTrace();

    } catch (IOException e) {

     // TODO Auto-generated catch block

     e.printStackTrace();

    }

             mp.start();

             isStart = true;

             return START;

            } else if(mp.isPlaying()) {

             mp.pause();

             return PAUSE;

            } else {

             mp.start();

             return PLAY;

            }

           

  }

  public void stopMusic() throws android.os.RemoteException {

            Log.i("CHEN""Stop music"); 

            if(mp.isPlaying()) {

             isStart = false;

             mp.stop();

            }

  }

  

  public int getCondition() throws android.os.RemoteException {

   if(mp == null)

    return UNCREATE;

   else if(!isStart)

    return STOP;

   else if(!mp.isPlaying())

    return PAUSE;

   else

    return PLAY;

  }

 };

 

 @Override

 public IBinder onBind(Intent arg0) {

  // TODO Auto-generated method stub

  Log.v("MyService""Bind");

  return binder;

 }

 

 @Override

 public void onCreate() {

  // TODO Auto-generated method stub

  super.onCreate();

  Log.v("MyService""Create");

 }

 

 @Override

 public boolean onUnbind(Intent intent) {

  // TODO Auto-generated method stub

  Log.v("MyService""Unbind");

  return true;

 }

 

 @Override

 public void onRebind(Intent intent) {

  // TODO Auto-generated method stub

  super.onRebind(intent);

  Log.v("MyService""Rebind");

 }

 

}

Activity当中

package android.mp3player;

import java.io.IOException;

import android.app.Activity;

import android.content.ComponentName;

import android.content.Context;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.Bundle;

import android.os.IBinder;

import android.os.RemoteException;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.ImageButton;

public class Mp3Player extends Activity {

 private Context mContext;

 private ImageButton bt1;

 private ImageButton bt2;

 private Intent intent;

 public MusicControlService musicControlService;

 private ServiceConnection sc;

 

 @Override

 public void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState); 

  setContentView(R.layout.main);

  bt1 = (ImageButton) findViewById(R.id.iButton01);

  bt2 = (ImageButton) findViewById(R.id.iButton02);

  bt1.setBackgroundResource(R.drawable.ibtbg);

  bt2.setBackgroundResource(R.drawable.ibtbg);

  mContext = this;

  

  //将Mp3Player与MyService绑定

  intent = new Intent(mContext, MyService.class);

  sc = new ServiceConnection() {

   public void onServiceConnected(ComponentName arg0, IBinder iBinder) {

    // TODO Auto-generated method stub

    musicControlService = MusicControlService.Stub.asInterface(iBinder);

    //如果希望程序能够取得Service中的信息, 请将代码写在ServiceConnected方法中, 写在外部 onCreate

    //或是 onStart程序无法执行(参照之前我说的执行顺序)

    try {

     if(musicControlService.getCondition() == MyService.PLAY)

     {

      bt1.setImageResource(R.drawable.ibt3);

      Log.v("ServiceConnection""Pause Button replaced");

     }

     else {

      bt1.setImageResource(R.drawable.ibt1);

      Log.v("ServiceConnection""Play Button replaced");

     }

    } catch (RemoteException e) {

     // TODO Auto-generated catch block

     e.printStackTrace();

     Log.v("MusicControlService""fail init");

    }

   }

   public void onServiceDisconnected(ComponentName arg0) {

    // TODO Auto-generated method stub

    musicControlService = null;

   }

  };

  bindService(intentsc, BIND_AUTO_CREATE);

  startService(intent);

  Log.v("mp3player""Create");

 }

 

 @Override

 protected void onStart() {

  // TODO Auto-generated method stub

  super.onStart();

  

  bt1.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {

    // TODO Auto-generated method stub

    Log.v("Mp3playerbt1""Clicked");

    try {

     if(musicControlService.playMusic() == MyService.PAUSE) {

      bt1.setImageResource(R.drawable.ibt1);

     } else {

      bt1.setImageResource(R.drawable.ibt3);

     }

    } catch (RemoteException e) {

     // TODO Auto-generated catch block

     e.printStackTrace();

    }

   }

   

  });

  bt2.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {

    // TODO Auto-generated method stub

    Log.v("Mp3playerbt2""Clicked");

    try {

     musicControlService.stopMusic();

     bt1.setImageResource(R.drawable.ibt1);

    } catch (RemoteException e) {

     // TODO Auto-generated catch block

     e.printStackTrace();

    }

   }

  });

 }

 

 @Override

 protected void onStop() {

  // TODO Auto-generated method stub

  super.onStop();

  Log.v("Mp3Player""Stop");

 }

 

 @Override

 protected void onDestroy() {

  // TODO Auto-generated method stub

  unbindService(sc);

  super.onDestroy();

  Log.v("Mp3Player""Destroy");

 }

}



你可能感兴趣的:(关于Android中Service与Activity的信息交互)