您的位置:首页 > 移动开发 > Android开发

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

2015-01-21 12:28 260 查看

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(intent, sc, 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");

}

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: