这是目前访问量最多的一篇博客了、今天不小心点开,发现写的不够好,所以修补一下。毕竟当初写这篇文章时还很年轻,哈哈~。
最重要是的利用了Messenger,Messenger可以翻译为信使,通过它可以再不同进程中传递对象,更不用说我们 没对service设置新进程了。Messenger是一种轻量级的IPC(跨进程通信)解决方案,底层是AIDL。
在写音乐播放器的时候用到了这个东西,相当于Activity中把mHandler用Messenger这个信封包裹着传递到了到了Service。Service拿到这个信封,信封里面装着mHandler,告诉service往里面装信息,然后信封再邮寄给mHandler。我们看一下Messenger的两个构造方法和一个send方法
/**
* Create a new Messenger pointing to the given Handler. Any Message
* objects sent through this Messenger will appear in the Handler as if
* {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had
* been called directly.
*
* @param target The Handler that will receive sent messages.
*/
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
/**
* Send a Message to this Messenger's Handler.
*
* @param message The Message to send. Usually retrieved through
* {@link Message#obtain() Message.obtain()}.
*
* @throws RemoteException Throws DeadObjectException if the target
* Handler no longer exists.
*/
public void send(Message message) throws RemoteException {
mTarget.send(message);
}
/**
* Create a Messenger from a raw IBinder, which had previously been
* retrieved with {@link #getBinder}.
*
* @param target The IBinder this Messenger should communicate with.
*/
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
我们通过new Messenger(mHander)得到一个Messenger对象。这个对象开始和Handler绑定到一起了。从此用这个Messenger对象发送的message都由构造对象时handler来处理。
通过Messenger不但可以服务给Activity通信,还可以Activity和Service通信。点击下载Demo
Activity中的主要代码:
1.开启我的服务的方法
private void startMyService(String option, String path) {
Intent service = new Intent(this, MyService.class);
service.putExtra("option", option);
service.putExtra("messenger", new Messenger(mHandler));
service.putExtra("path", path);
startService(service);
}
2,Activity中的handler
private Handler mHandler = new Handler() {
// 接收结果,刷新界面
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
break;
case 2:
break;
}
};
};
Service中接收Activity中传递过来的messenger信封,在Service的的startCommand()方法中:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String option = intent.getStringExtra("option");
if (mMessenger == null) {
mMessenger = (Messenger) intent.getExtras().get("messenger");
}
return super.onStartCommand(intent, flags, startId);
}
下面这个方法里面用到了Timer,在里面一直执行向Activity中的mHandler发送数据。
public void onPrepared(MediaPlayer mp) {
if (mTimer == null) {
mTimer = new Timer();
}
/**
* @Params task the task to schedule. delay amount of time in
* milliseconds before first execution. @Params period amount of
* time in milliseconds between subsequent executions.
*/
mTimer.schedule(new TimerTask() {
@Override
public void run() {
// 1.准备好的时候告诉activity,当前歌曲的总时长
int currentPosition = mPlayer.getCurrentPosition();
int duration = mPlayer.getDuration();
Message message = Message.obtain();
message.what = Constants.MSG_ONPREPARED;
message.arg1 = currentPosition;
message.arg2 = duration;
try {
mMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}, 0, 1000);
}