android-使用ADIL进行跨进程调用

1.跨进程调用

   Android提供了一个轻量级的跨进程调用机制。如果想使用远程调用,可以使用AIDL(android

   interface description language:android描述接口语言)实现。它用来声明接口里的方法

   (.aidl文件),使用AIDL工具或其他编译工具,build该文件成java源文件,该java源文件会自动

   包含一个stub抽象类(Binder的子类,即相当于Binder),开发者需要实现stub类中的抽象的方法

   以便客户端调用。

客户端通过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);
              }
        });

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。