Android 基础总结:( 二十一)AIDL详解(下)

来源:互联网 发布:服务器端软件 编辑:程序博客网 时间:2024/06/13 11:13

Android 跨进程通信(一)

一. 概述:

跨进程通信(AIDL),主要实现进程(应用)间数据共享功能。

二. 实现流程:

1. 服务器端实现:

(1)目录结构,如下图:

(2)实现*.aidl文件:

A. IAIDLService.aidl实现:

[java] view plain copy
 print?
  1. interface IAIDLService {  
  2.     String getName();  
  3.     Person getPerson();  
  4. }  

B. Person.aidl实现:

parcelable Person;

(3)进程间传递对象必需实现Parcelable或Serializable接口,下面是被传递的Person对象实现:

[java] view plain copy
 print?
  1. public class Person implements Parcelable {  
  2.     private String name;  
  3.     private int age;  
  4.     public Person() {  
  5.     }  
  6.     public Person(Parcel source) {  
  7.         name = source.readString();  
  8.         age = source.readInt();  
  9.     }  
  10.     public String getName() {  
  11.         return name;  
  12.     }  
  13.     public void setName(String name) {  
  14.         this.name = name;  
  15.     }  
  16.     public int getAge() {  
  17.         return age;  
  18.     }  
  19.     public void setAge(int age) {  
  20.         this.age = age;  
  21.     }  
  22.     public int describeContents() {  
  23.         return 0;  
  24.     }  
  25.     public void writeToParcel(Parcel dest, int flags) {  
  26.         dest.writeString(name);  
  27.         dest.writeInt(age);  
  28.     }  
  29.     public static final Parcelable.Creator<Person> CREATOR = new Creator<Person>() {  
  30.         public Person[] newArray(int size) {  
  31.             return new Person[size];  
  32.         }  
  33.         public Person createFromParcel(Parcel source) {  
  34.             return new Person(source);  
  35.         }  
  36.     };  
  37. }  
(4)实现IAIDLService.aidl文件中定义的接口,并定义Service,在Service被bind时返回此实现类:

[java] view plain copy
 print?
  1. public class AIDLServiceImpl extends Service {  
  2.     @Override  
  3.     public IBinder onBind(Intent intent) {  
  4.         return mBinder;  
  5.     }  
  6.     /** 
  7.      * 在AIDL文件中定义的接口实现。 
  8.      */  
  9.     private IAIDLService.Stub mBinder = new Stub() {  
  10.         public String getName() throws RemoteException {  
  11.             return "mayingcai";  
  12.         }  
  13.         public Person getPerson() throws RemoteException {  
  14.             Person mPerson = new Person();  
  15.             mPerson.setName("mayingcai");  
  16.             mPerson.setAge(24);  
  17.             return mPerson;  
  18.         }  
  19.     };  
  20. }  
(5)在AndroidManifest.xml文件中注册Service:

[html] view plain copy
 print?
  1. <service android:name = ".AIDLServiceImpl" android:process = ":remote">  
  2.     <intent-filter>  
  3.         <action android:name = "com.focus.aidl.IAIDLService" />  
  4.     </intent-filter>  
  5. </service>  


Android 跨进程通信(二)

2. 客户端实现:

(1)目录结构,如下图:

(2)将服务器端的IAIDLService.aidl,Person.aidl和Person.Java文件拷贝到本工程中,如上图所示:

(3)res/layout/main.xml实现:

[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android  
  3.     android:layout_width="fill_parent  
  4.     android:layout_height="fill_parent  
  5.     android:orientation="vertical" >  
  6.     <TextView  
  7.         android:id="@+id/name  
  8.         android:layout_width="wrap_content  
  9.         android:layout_height="wrap_content" />  
  10.     <Button  
  11.         android:id="@+id/connection  
  12.         android:layout_width="wrap_content  
  13.         android:layout_height="wrap_content  
  14.         android:text="连接" />  
  15.     <Button  
  16.         android:id="@+id/message  
  17.         android:layout_width="wrap_content  
  18.         android:layout_height="wrap_content  
  19.         android:enabled="false  
  20.         android:text="信息" />  
  21.     <Button  
  22.         android:id="@+id/person  
  23.         android:layout_width="wrap_content  
  24.         android:layout_height="wrap_content  
  25.         android:enabled="false  
  26.         android:text="人" />  
  27. </LinearLayout>  
(4)主Activity实现,从服务器端获取数据在客户端显示:

[java] view plain copy
 print?
  1. public class AIDLClientAcitivty extends Activity {  
  2.     private IAIDLService mAIDLService;  
  3.     private TextView mName;  
  4.     private Button mMessage;  
  5.     private Button mPerson;  
  6.     /** 
  7.      * 第一步,创建ServiceConnection对象,在onServiceConnected()方法中获取IAIDLService实现。 
  8.      */  
  9.     private ServiceConnection mServiceConnection = new ServiceConnection() {  
  10.         public void onServiceConnected(ComponentName name, IBinder service) {  
  11.             mAIDLService = IAIDLService.Stub.asInterface(service);  
  12.             mMessage.setEnabled(true);  
  13.             mPerson.setEnabled(true);  
  14.         }  
  15.         public void onServiceDisconnected(ComponentName name) {  
  16.             mAIDLService = null;  
  17.             mMessage.setEnabled(false);  
  18.             mPerson.setEnabled(false);  
  19.         }  
  20.     };  
  21.     @Override  
  22.     public void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.main);  
  25.         mName = (TextView) findViewById(R.id.name);  
  26.         findViewById(R.id.connection).setOnClickListener(new OnClickListener() {  
  27.             public void onClick(View view) {  
  28.                 /** 
  29.                  * 第二步,单击"连接"按钮后用mServiceConnection去bind服务器端创建的Service。 
  30.                  */  
  31.                 Intent service = new Intent("com.focus.aidl.IAIDLService");  
  32.                 bindService(service, mServiceConnection, BIND_AUTO_CREATE);  
  33.             }  
  34.         });  
  35.         mMessage = (Button) findViewById(R.id.message);  
  36.         mMessage.setOnClickListener(new OnClickListener() {  
  37.             public void onClick(View view) {  
  38.                 /** 
  39.                  * 第三步,从服务器端获取字符串。 
  40.                  */  
  41.                 try {  
  42.                     mName.setText(mAIDLService.getName());  
  43.                 } catch (RemoteException e) {  
  44.                     e.printStackTrace();  
  45.                 }  
  46.             }  
  47.         });  
  48.         mPerson = (Button) findViewById(R.id.person);  
  49.         mPerson.setOnClickListener(new OnClickListener() {  
  50.             public void onClick(View view) {  
  51.                 /** 
  52.                  * 第四步,从服务器端获取Person对象。 
  53.                  */  
  54.                 try {  
  55.                     Person mPerson = mAIDLService.getPerson();  
  56.                     mName.setText("姓名:" + mPerson.getName() + ", 年龄:  
  57.                             + mPerson.getAge());  
  58.                 } catch (RemoteException e) {  
  59.                     e.printStackTrace();  
  60.                 }  
  61.             }  
  62.         });  
  63.     }  
  64. }  


通过AIDL调用Service

在网上找的一些关于service的例子都比较简单,都是通过startService("action")启动service,然后通过stopService("service")停止service。只能启动和停止service没有发挥service的功能。下面我通过介绍关于AIDL启动service来控制音乐播放的例子来说明通过前台控制service的使用。

1.在工程的包中一个后缀为aidl的文件:

[java] view plain copy
 print?
  1. IMusicControlService.aidl  
package com.androidmanual.androidstud2.service;--------包名一定要和当前工程的包名一样哦!

[java] view plain copy
 print?
  1. interface IMusicControlService  
  2. {  
  3.     voidplayMusic();-------->播放音乐  
  4.     voidstopMusic();------->停止播放音乐  
  5. }  

点击保存后,在gen/上述包名的目录下就创建了一个IMusicControlService.java文件了

2.在res/layout目录下创建布局文件:

startserviceactivity.xml

[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android  
  3.     android:layout_width="fill_parent  
  4.     android:layout_height="fill_parent  
  5.     android:orientation="vertical" >  
  6.     <TextView  
  7.         android:id="@+id/tv_main  
  8.         android:layout_width="fill_parent  
  9.         android:layout_height="wrap_content  
  10.         android:text="@string/hello  
  11.         android:textSize="18px" />  
  12.     <Button  
  13.         android:id="@+id/btn_play  
  14.         android:layout_width="wrap_content  
  15.         android:layout_height="wrap_content  
  16.         android:text="播放音乐" />  
  17.     <Button  
  18.         android:id="@+id/btn_stop  
  19.         android:layout_width="wrap_content  
  20.         android:layout_height="wrap_content  
  21.         android:text="停止播放" />  
  22. </LinearLayout>  
3.创建一个service类,在该类的内部实例化IMusicControlService中的playMusic()和stopMusic()接口
[java] view plain copy
 print?
  1. private final IMusicControlService.Stub binder = new IMusicControlService.Stub() {  
  2.     @Override  
  3.     public void playMusic() throws RemoteException {  
  4.         player = MediaPlayer.create(ControlMusicService.this,  
  5.                 R.raw.shanghaitan);  
  6.         player.start();  
  7.     }  
  8.     @Override  
  9.     public void stopMusic() throws RemoteException {  
  10.         if (player.isPlaying()) {  
  11.             player.stop();  
  12.         }  
  13.     }  
  14. };  

在该类的onBind()方法中返回上面实例的binder,即returnbinder;

4.创建StartServiceActivity类继承Activity类,在该类中通过ServiceConnection和后台的service连接

[java] view plain copy
 print?
  1. private final ServiceConnection serviceConnection = new ServiceConnection() {  
  2.     // 第一次连接service时会调用这个方法  
  3.     @Override  
  4.     public void onServiceConnected(ComponentName name, IBinder service) {  
  5.         iMusicControlService = IMusicControlService.Stub  
  6.                 .asInterface(service);  
  7.     }  
  8.     // service断开的时候会调用这个方法  
  9.     @Override  
  10.     public void onServiceDisconnected(ComponentName name) {  
  11.         // TODO Auto-generated method stub  
  12.         System.out.println("service unconntection");  
  13.         iMusicControlService = null;  
  14.     }  
  15. };  
在oncreate方法中绑定service:

[java] view plain copy
 print?
  1. Intent intent= new Intent();  
  2. intent.setClass(StartServiceActivity.this,ControlMusicService.class);  
  3. bindService(intent,serviceConnection,Context.BIND_AUTO_CREATE);  
在点击playmusic按钮被点击时,执行如下代码:

[java] view plain copy
 print?
  1. iMusicControlService.playMusic();  

在点击stopmusic按钮被点击时,执行如下代码:

[java] view plain copy
 print?
  1. iMusicControlService.stopMusic();  
  2. unbindService(serviceConnection);  

好了这样就通过在Activity中通过aidl控制service了。
1 0
原创粉丝点击