傻蛋在Android Service(4) 中讲述了使用AIDL语言,来让ADT帮助我们自动生成一个Stub类(Binder的子类),来实现不同进程中Service的调用。通过研究ADT自动生成的代码可以发现,这段代码其实是帮我们实现了一个代理类,这个代理能够通过进行不同进程间的通信。我们Activity调用这个代理类,而这个调用远程Service中的方法。从而实现了远程通信。
今天傻蛋自己写了一个底层远程通信的代理类(具体通信方式傻蛋在第6篇中已经讲了),同样实现了远程调用Service的效果。基本结构和ADT自动生成的代码相似,但是清晰了很多,使用方法和第四篇中的使用一某一样,十分通用。
?[Copy to clipboard]
Download IMyMusicService.java
- /**
- * IMusicService.java
- * com.androidtest.service.mediaplayer
- *
- * Function: TODO
- *
- * ver date author
- * ──────────────────────────────────
- * 2011-6-22 Leon
- *
- * Copyright (c) 2011, TNT All Rights Reserved.
- */
- package com.androidtest.service.remoteplayer;
- import android.os.Binder;
- import android.os.IBinder;
- import android.os.Parcel;
- import android.os.RemoteException;
- import android.util.Log;
- /**
- * ClassName:IMusicService Function: TODO ADD FUNCTION Reason: TODO ADD REASON
- *
- * @author Leon
- * @version
- * @since Ver 1.1
- * @Date 2011-6-22
- */
- public interface IMyMusicService {
- static final String TAG = IMyMusicService.class.getSimpleName();
- static final int TRANSACTION_PLAY = android.os.IBinder.FIRST_CALL_TRANSACTION + 0;
- static final int TRANSACTION_PAUSE = android.os.IBinder.FIRST_CALL_TRANSACTION + 1;
- static final int TRANSACTION_STOP = android.os.IBinder.FIRST_CALL_TRANSACTION + 2;
- public void play() throws RemoteException ;
- public void pause()throws RemoteException ;
- public void stop() throws RemoteException ;
- public static abstract class Stub extends Binder implements IMyMusicService {
- //用于Service的接收
- @Override
- protected boolean onTransact(int code, Parcel data, Parcel reply,
- int flags) throws RemoteException {
- // TODO Auto-generated method stub
- switch (code) {
- case TRANSACTION_PLAY:
- this.play();
- /**
- * 注意 readString 是这样解释
- * Read a string value from the parcel at the current dataPosition().
- * 第二次读的话data position就会前移,此处就为null了
- */
- String temp = data.readString();
- Log.v(TAG,"The Message From Clinet : "+temp);
- reply.writeString(temp);
- return true;
- case TRANSACTION_PAUSE:
- this.pause();
- Log.v(TAG,"The Message From Clinet : "+data.readString());
- reply.writeString(data.readString());
- return true;
- case TRANSACTION_STOP:
- this.stop();
- Log.v(TAG,"The Message From Clinet :"+data.readString());
- reply.writeString(data.readString());
- return true;
- }
- return super.onTransact(code, data, reply, flags);
- }
- //模板模式
- public abstract void play() throws RemoteException ;
- public abstract void pause() throws RemoteException ;
- public abstract void stop() throws RemoteException ;
- //其实就是获取代理类,供Activity来调用
- public static IMyMusicService asInterface(IBinder iBinder){
- return new Proxy(iBinder);
- }
- //Activity其实就是通过此代理和远程的Stub进行通信
- private static class Proxy implements IMyMusicService{
- private IBinder iBinder;
- public Proxy(IBinder iBinder) {
- this.iBinder =iBinder;
- }
- @Override
- public void pause() {
- Parcel sendData = Parcel.obtain();
- Parcel replyData =Parcel.obtain();
- sendData.writeString("pause");
- try {
- iBinder.transact(TRANSACTION_PAUSE, sendData, replyData, 0);
- Log.v(TAG, "The Message From Service " + replyData.readString() );
- } catch (RemoteException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- // TODO Auto-generated method stub
- }
- @Override
- public void play() {
- // TODO Auto-generated method stub
- Parcel sendData = Parcel.obtain();
- Parcel replyData =Parcel.obtain();
- sendData.writeString("play");
- try {
- iBinder.transact(TRANSACTION_PLAY, sendData, replyData, 0);
- Log.v(TAG, "The Message From Service " + replyData.readString());
- } catch (RemoteException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- @Override
- public void stop() {
- // TODO Auto-generated method stub
- Parcel sendData = Parcel.obtain();
- Parcel replyData =Parcel.obtain();
- sendData.writeString("stop");
- try {
- iBinder.transact(TRANSACTION_STOP, sendData, replyData, 0);
- Log.v(TAG, "The Message From Service " + replyData.readString() );
- } catch (RemoteException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- }
- /**
- * MyRemoteBinder.java
- * com.androidtest.service.remoteplayer
- *
- * Function: TODO
- *
- * ver date author
- * ──────────────────────────────────
- * 2011-6-22 Leon
- *
- * Copyright (c) 2011, TNT All Rights Reserved.
- */
- package com.androidtest.service.remoteplayer;
- import android.media.MediaPlayer;
- import android.os.RemoteException;
- import com.androidtest.service.mediaplayer.MyMediaController;
- /**
- * ClassName:MyRemoteBinder
- * Function: TODO ADD FUNCTION
- * Reason: TODO ADD REASON
- *
- * @author Leon
- * @version
- * @since Ver 1.1
- * @Date 2011-6-22
- */
- public class MyCustomRemoteBinder extends IMyMusicService.Stub{
- public MyCustomRemoteBinder(MediaPlayer mediaPlayer){
- MyMediaController.mediaPlayer=mediaPlayer ;
- };
- @Override
- public void play() throws RemoteException {
- // TODO Auto-generated method stub
- MyMediaController.play.execute();
- }
- @Override
- public void pause() throws RemoteException {
- // TODO Auto-generated method stub
- MyMediaController.pause.execute();
- }
- @Override
- public void stop() throws RemoteException {
- // TODO Auto-generated method stub
- MyMediaController.stop.execute();
- };
- }
本篇是Android Service的思考(7)的完结篇,Service用起来不难,但是理解其中的机制就有一定的难度了,尤其是远程调用一定要对远程代理有深刻的认识才行。本系列设计的源码很多,如果有人需要请加最牛网的群找傻蛋索要。
本文转自 最牛傻蛋 51CTO博客,原文链接:http://blog.51cto.com/zuiniuwang/718284,如需转载请自行联系原作者