1.使用service组件
2.跨进程调用
Android提供了一个轻量级的跨进程调用机制。如果想使用远程调用,可以使用AIDL(android
interface description language:android描述接口语言)实现。它用来声明接口里的方法
(.aidl文件),使用AIDL工具或其他编译工具,build该文件成java源文件,该java源文件会自动
包含一个stub抽象类(Binder的子类,即相当于Binder),开发者需要实现stub类中的抽象的方法
以便客户端调用。
3.创建AIDL接口文件(IPC传输)
AIDL文件只能声明方法,方法中可以包含输入参数和返回值,AIDL支持的类型包括Java基本类型,String,CharSequence,
以及List和Map两种集合。如果你想除了传输上述的数据类型,还想再IPC中传输你自定义的Object,则可该Object类型必须
继承Parcelable接口,可以在IPC中传输。
4.案例
客户端通过IBinder远程操作服务端的音乐播放器。
思想:接口的方法声明提供给客户端调用,接口的方法在服务端实现。
通过绑定service后的ServiceConnection返回控制服务端的接口。
步骤:
客户端:
调用bindService(intent,conn,Context.BIND_AUTO_CREATE)方法,绑定服务端。
调用 unbindService(conn)方法,解除绑定服务端。
ServiceConnection conn=new ServiceConnection() {
//当绑定时自动调用,即 bindService方法调用时
@Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
//返回binder,通过binder的方法对播放器进行操作
service =IPlayback.Stub.asInterface(iBinder);
Log.v("信息","ServiceConnection,调用onServiceConnection");
}
//当解除绑定时自动调用,即unbindService方法调用时
@Override
public void onServiceDisconnected(ComponentName name) {
Log.v("信息","ServiceConnection,调用onServiceDisconnected");
}
};
该ServiceConnection是连接服务端的“一条线”,它的onServiceConnected方法会返回,
你用AIDL创建的IPlayback.aidl文件里的IPlayback接口提供的方法返回一个IPlayback接口,
该接口里的方法用来控制服务端的播放器。
服务端:创建一个stub对象实现AIDL接口里的方法,并在onBind方法里,放回该stub
第一步:
新建一个文件IPlayback.aidl文件,在里面声明你要控制服务端播放器的方法
该文件的包名最好与使用它的客户端包名同名,在Android studio下点击build->rebuild project
即可生成该.aidl文件的java源文件。
package com.example.administrator.servicedemo;
interface IPlayback{
//播放功能的方法
void start();
void pause();
void stop();
void release();
void previous();
void next();
boolean isPlaying();
第二步:
该接口的方法在服务端实现并控制播放器
public class MusicService extends Service{
//多媒体播放器对象,歌曲的路径
private MediaPlayer mp=null;
private String path= Environment.getExternalStorageDirectory()+"/Music/knokc.mp3";
private NotificationManager notifyManager=null;
//这里的bind实现ADIL接口里的方法
private IBinder binder=new IPlayback.Stub(){
@Override
public void stop() throws RemoteException {
if(mp!=null)
mp.stop();
Log.v("mediaplayer","stop()");
}
@Override
public void start() throws RemoteException {
if(mp!=null)
mp.start();
Log.v("mediaplayer","start()");
}
@Override
public void pause() throws RemoteException {
if(mp!=null)
mp.pause();
}
@Override
public void release() throws RemoteException {
}
@Override
public void previous() throws RemoteException {
//前一首歌
}
@Override
public void next() throws RemoteException {
//下一首歌
}
};
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
//采用绑定service的方式后,返回该实现的binder给客户端
return binder;
}
@Override
public void onCreate() {
super.onCreate();
//初始化工作,准备好,等待start播放音乐
mp=new MediaPlayer();
mp.reset();
try {
mp.setDataSource(path);
mp.prepare();
} catch ( Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//只有以startservice的方式才调用该方法
// 每次startService()方法调用时,该方法响应,
//判断是否在播放,使其播放或停止
if(mp.isPlaying())
mp.pause();
else
mp.start();
//showNotification();
return Service.START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
//释放Mediaplayer对象
mp.release();
}
}
}
第三步:
在客户端绑定service并接收binder
public class MusicActivity extends Activity {
private Button bt=null;
private Button bt1=null;
private Button bt2=null;
private MusicReceiver mr=null;
//该service是IPlayback接口返回的对象,实现对播放器的控制
private IPlayback service=null;
private ServiceConnection conn=new ServiceConnection() {
//当绑定时自动调用,即 bindService方法调用时
@Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
//返回binder,通过binder的方法对播放器进行操作
service =IPlayback.Stub.asInterface(iBinder);
}
//当解除绑定时自动调用,即unbindService方法调用时
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music);
bt1=(Button)findViewById(R.id.bt1);
bt2=(Button)findViewById(R.id.bt2);
bt=(Button)findViewById(R.id.bt);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//绑定service
Intent intent =new Intent(MusicActivity.this,MusicService.class);
bindService(intent,conn,Context.BIND_AUTO_CREATE);
}
});
bt1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
if(service.isPlaying())
service.stop();
else
service.start();
}catch(Exception e)
{
e.printStackTrace();
}
}
});
bt2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//解除绑定,可在destroy方法中解除绑定
unbindService(conn);
}
});