Android:AIDL创建Service

简述:

1. Android开发中会用到Service这个类,Service用于实现进程间方法的调用,UI中调用音乐播放服务就用到Service,起到跨进程通信的作用

2. AIDL: Android Interface Definition Language,Android内部进程通信接口的描述语言,通过他可以定义进程间通信接口,结合service在后台运作,暴露接口用来和当前程序通信

3,.Android 提供了Parcel类型,Parcel用作封装数据的容器,封装后的数据可以通过Intent或IPC传递,除了基本类型之外,只有实现了Parcelable接口的类才能被放入Parcel


本文参考:

http://blog.csdn.net/stonecao/article/details/6425019

http://blog.csdn.net/liuhe688/article/details/6409708

http://blog.sina.com.cn/s/blog_78e3ae430100pxba.html


知识点:

1. Android service

2. AIDL的使用,在aidl文件中复杂类型的导入

3. Parcelable接口的使用


项目工程文件目录

其中gen下的com.atp.aidl是AIDL自带生成的(clean->build之后就能生成)



代码:

com.atp.aidl包

Fruit.java

[java]  view plain copy
  1. package com.atp.aidl;  
  2.   
  3. import android.os.Parcel;  
  4. import android.os.Parcelable;  
  5.   
  6. public class Fruit implements Parcelable {  
  7.     private String name;  
  8.     private Integer size;  
  9.     public Fruit(String name, Integer size) {  
  10.         this.name = name;  
  11.         this.size = size;  
  12.     }  
  13.       
  14.     public Fruit(Parcel source) {  
  15.          readFromParcel(source);  
  16.     }  
  17.     public String getName() {  
  18.         return name;  
  19.     }  
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23.     public Integer getsize() {  
  24.         return size;  
  25.     }  
  26.     public void setsize(Integer size) {  
  27.         this.size = size;  
  28.     }  
  29.     @Override  
  30.     public String toString() {  
  31.         return "[name: " + name + ", size: " + size + "]";  
  32.     }  
  33.       
  34.       
  35.     //AIDL needs CREATOR static final android.os.Parcelable.Creator<T> to call service  
  36.     public static final Parcelable.Creator<Fruit> CREATOR = new Parcelable.Creator<Fruit>() {    
  37.         @Override    
  38.         public Fruit createFromParcel(Parcel source) {    
  39.             return new Fruit(source);  
  40.         }  
  41.     
  42.         @Override    
  43.         public Fruit[] newArray(int size) {    
  44.             return new Fruit[size];    
  45.         }    
  46.     };    
  47.       
  48.     @Override  
  49.     public int describeContents() {  
  50.         return 0;  
  51.     }  
  52.       
  53.     //write and read must in the same sequence  
  54.     @Override  
  55.     public void writeToParcel(Parcel dest, int flags) {  
  56.         dest.writeString(name);  
  57.         dest.writeInt(size);  
  58.     }  
  59.       
  60.     public void readFromParcel(Parcel source) {    
  61.         name = source.readString();    
  62.         size = source.readInt();    
  63.     }    
  64. }  

Fruit.aidl 复杂类型的aidl文件

[plain]  view plain copy
  1. package com.atp.aidl;  
  2. parcelable Fruit;  

ITestService.aidl的接口文件

[plain]  view plain copy
  1. package com.atp.aidl;  
  2.   
  3. import com.atp.aidl.Fruit;  
  4.   
  5. interface ITestService {  
  6.     String getSomething();  
  7.     Fruit getFruit();  
  8. }  

com.atp.service包

[java]  view plain copy
  1. package com.atp.service;  
  2.   
  3. import com.atp.aidl.Fruit;  
  4. import com.atp.aidl.ITestService;  
  5.   
  6. import android.app.Service;  
  7. import android.content.Intent;  
  8. import android.os.IBinder;  
  9. import android.os.RemoteException;  
  10. import android.util.Log;  
  11.   
  12.   
  13. public class MyService extends Service{  
  14.     public static final String TAG = "com.atp.ui.MyService";  
  15.   
  16.     private class MyServiceImpl extends ITestService.Stub{  
  17.   
  18.         @Override  
  19.         public String getSomething() throws RemoteException {  
  20.             Log.e(TAG, "getSomething");  
  21.             return "Apple";  
  22.         }  
  23.   
  24.         @Override  
  25.         public Fruit getFruit() throws RemoteException {  
  26.             Fruit fruit = new Fruit("Banana"10);  
  27.             return fruit;  
  28.         }  
  29.   
  30.     }  
  31.       
  32.     @Override  
  33.     public IBinder onBind(Intent arg0) {  
  34.         //return implementation of AIDL  
  35.         return new MyServiceImpl();  
  36.     }  
  37.       
  38.     @Override  
  39.     public void onDestroy() {  
  40.         Log.e(TAG, "Release MyService");  
  41.         super.onDestroy();  
  42.     }  
  43. }  

com.atp.ui包

MainActivity.java

[java]  view plain copy
  1. package com.atp.ui;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.ComponentName;  
  5. import android.content.Context;  
  6. import android.content.Intent;  
  7. import android.content.ServiceConnection;  
  8. import android.os.Bundle;  
  9. import android.os.IBinder;  
  10. import android.os.RemoteException;  
  11. import android.util.Log;  
  12. import android.view.View;  
  13. import android.widget.Button;  
  14. import android.widget.TextView;  
  15.   
  16. import com.atp.R;  
  17. import com.atp.aidl.Fruit;  
  18. import com.atp.aidl.ITestService;  
  19. import com.atp.service.MyService;  
  20.   
  21. public class MainActivity extends Activity {  
  22.     public static final String TAG = "com.atp.ui.MainActivity";  
  23.   
  24.     private Button myBtn = null;  
  25.     private TextView myTv = null;  
  26.   
  27.     @Override  
  28.     protected void onCreate(Bundle savedInstanceState) {  
  29.         super.onCreate(savedInstanceState);  
  30.         setContentView(R.layout.main_activity);  
  31.         myBtn = (Button) findViewById(R.id.myBtn);  
  32.         myTv = (TextView) findViewById(R.id.myTv);  
  33.         myBtn.setOnClickListener(new View.OnClickListener() {  
  34.             @Override  
  35.             public void onClick(View arg0) {  
  36.                 bindMyService();  
  37.             }  
  38.         });  
  39.     }  
  40.       
  41.     private ITestService iService = null;  
  42.     private ServiceConnection conn = new ServiceConnection(){  
  43.         private String resultFromService;  
  44.         private Fruit fruitFromService;  
  45.         @Override  
  46.         public void onServiceConnected(ComponentName name, IBinder service) {  
  47.             //return AIDL object,then call methods of AIDL  
  48.             iService = ITestService.Stub.asInterface(service);  
  49.             try {  
  50.                 resultFromService = iService.getSomething();  
  51.                 fruitFromService = iService.getFruit();  
  52.             } catch (RemoteException e) {  
  53.                 Log.e(TAG, "Error while call on iService!");  
  54.                 e.printStackTrace();  
  55.             }  
  56.             Log.e(TAG, "something is:" + resultFromService);  
  57.             myTv.setText("something is:" + resultFromService + "\n"  
  58.                     + "fruit: " + fruitFromService.toString());  
  59.         }  
  60.   
  61.         @Override  
  62.         public void onServiceDisconnected(ComponentName arg0) {  
  63.             Log.i(TAG, "release iService");  
  64.         }  
  65.     };  
  66.       
  67.       
  68.      private void bindMyService(){  
  69.          Intent intent = new Intent(this, MyService.class);  
  70.          startService(intent);  
  71.          bindService(intent, conn, Context.BIND_AUTO_CREATE);  
  72.      }   
  73. }  

视图xml文件
main_activity.xml

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/mainRelativeLayout"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     >  
  7.   
  8.     <Button  
  9.         android:id="@+id/myBtn"  
  10.         android:layout_width="wrap_content"  
  11.         android:layout_height="wrap_content"  
  12.         android:text="Start"  
  13.         android:textSize="22dip"  
  14.          />  
  15.       
  16.     <TextView  
  17.         android:id="@+id/myTv"  
  18.         android:layout_width="500dip"  
  19.         android:layout_height="100dip"  
  20.         android:layout_below="@id/myBtn"  
  21.         android:text="Text Area"   
  22.         android:textSize="22dip"/>  
  23.   
  24. </RelativeLayout>  

下面是在AndroidManifest.xml注册这个service

其中对于android:process这一属性的解释:

android:process=":remote",代表在应用程序里,当需要该service时,会自动创建新的进程。而如果是android:process="remote",没有“:”分号的,则创建全局进程,不同的应用程序共享该进程。

AndroidManifest.xml

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.atp"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk  
  8.         android:minSdkVersion="8"  
  9.         android:targetSdkVersion="21" />  
  10.   
  11.     <application  
  12.         android:allowBackup="true"  
  13.         android:icon="@drawable/ic_launcher"  
  14.         android:label="@string/app_name"  
  15.         android:theme="@style/AppTheme" >  
  16.         <activity  
  17.             android:name=".ui.MainActivity"  
  18.             android:label="@string/app_name" >  
  19.             <intent-filter>  
  20.                 <action android:name="android.intent.action.MAIN" />  
  21.                 <category android:name="android.intent.category.LAUNCHER" />  
  22.             </intent-filter>  
  23.         </activity>  
  24.         <service   
  25.             android:name=".service.MyService"  
  26.             android:process=":remote">  
  27.             <intent-filter>  
  28.                 <action android:name=".aidl.ITestService" />  
  29.             </intent-filter>  
  30.         </service>  
  31.     </application>  
  32.   
  33. </manifest>  

这是由com.atp.aidl下的aidl文件 自动generate出来的文件

ITestService.java

[java]  view plain copy
  1. /* 
  2.  * This file is auto-generated.  DO NOT MODIFY. 
  3.  * Original file: C:\\Users\\anialy.anialy-PC\\Desktop\\eclipse_work_space_2\\AndroidTestProject\\src\\com\\atp\\aidl\\ITestService.aidl 
  4.  */  
  5. package com.atp.aidl;  
  6. public interface ITestService extends android.os.IInterface  
  7. {  
  8.     /** Local-side IPC implementation stub class. */  
  9.     public static abstract class Stub extends android.os.Binder implements com.atp.aidl.ITestService  
  10.     {  
  11.         private static final java.lang.String DESCRIPTOR = "com.atp.aidl.ITestService";  
  12.         /** Construct the stub at attach it to the interface. */  
  13.         public Stub()  
  14.         {  
  15.             this.attachInterface(this, DESCRIPTOR);  
  16.         }  
  17.         /** 
  18.          * Cast an IBinder object into an com.atp.aidl.ITestService interface, 
  19.          * generating a proxy if needed. 
  20.          */  
  21.         public static com.atp.aidl.ITestService asInterface(android.os.IBinder obj)  
  22.         {  
  23.             if ((obj==null)) {  
  24.                 return null;  
  25.             }  
  26.             android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);  
  27.             if (((iin!=null)&&(iin instanceof com.atp.aidl.ITestService))) {  
  28.                 return ((com.atp.aidl.ITestService)iin);  
  29.             }  
  30.             return new com.atp.aidl.ITestService.Stub.Proxy(obj);  
  31.         }  
  32.         @Override public android.os.IBinder asBinder()  
  33.         {  
  34.             return this;  
  35.         }  
  36.         @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException  
  37.         {  
  38.             switch (code)  
  39.             {  
  40.             case INTERFACE_TRANSACTION:  
  41.             {  
  42.                 reply.writeString(DESCRIPTOR);  
  43.                 return true;  
  44.             }  
  45.             case TRANSACTION_getSomething:  
  46.             {  
  47.                 data.enforceInterface(DESCRIPTOR);  
  48.                 java.lang.String _result = this.getSomething();  
  49.                 reply.writeNoException();  
  50.                 reply.writeString(_result);  
  51.                 return true;  
  52.             }  
  53.             case TRANSACTION_getFruit:  
  54.             {  
  55.                 data.enforceInterface(DESCRIPTOR);  
  56.                 com.atp.aidl.Fruit _result = this.getFruit();  
  57.                 reply.writeNoException();  
  58.                 if ((_result!=null)) {  
  59.                     reply.writeInt(1);  
  60.                     _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);  
  61.                 }  
  62.                 else {  
  63.                     reply.writeInt(0);  
  64.                 }  
  65.                 return true;  
  66.             }  
  67.             }  
  68.             return super.onTransact(code, data, reply, flags);  
  69.         }  
  70.         private static class Proxy implements com.atp.aidl.ITestService  
  71.         {  
  72.             private android.os.IBinder mRemote;  
  73.             Proxy(android.os.IBinder remote)  
  74.             {  
  75.                 mRemote = remote;  
  76.             }  
  77.             @Override public android.os.IBinder asBinder()  
  78.             {  
  79.                 return mRemote;  
  80.             }  
  81.             public java.lang.String getInterfaceDescriptor()  
  82.             {  
  83.                 return DESCRIPTOR;  
  84.             }  
  85.             @Override public java.lang.String getSomething() throws android.os.RemoteException  
  86.             {  
  87.                 android.os.Parcel _data = android.os.Parcel.obtain();  
  88.                 android.os.Parcel _reply = android.os.Parcel.obtain();  
  89.                 java.lang.String _result;  
  90.                 try {  
  91.                     _data.writeInterfaceToken(DESCRIPTOR);  
  92.                     mRemote.transact(Stub.TRANSACTION_getSomething, _data, _reply, 0);  
  93.                     _reply.readException();  
  94.                     _result = _reply.readString();  
  95.                 }  
  96.                 finally {  
  97.                     _reply.recycle();  
  98.                     _data.recycle();  
  99.                 }  
  100.                 return _result;  
  101.             }  
  102.             @Override public com.atp.aidl.Fruit getFruit() throws android.os.RemoteException  
  103.             {  
  104.                 android.os.Parcel _data = android.os.Parcel.obtain();  
  105.                 android.os.Parcel _reply = android.os.Parcel.obtain();  
  106.                 com.atp.aidl.Fruit _result;  
  107.                 try {  
  108.                     _data.writeInterfaceToken(DESCRIPTOR);  
  109.                     mRemote.transact(Stub.TRANSACTION_getFruit, _data, _reply, 0);  
  110.                     _reply.readException();  
  111.                     if ((0!=_reply.readInt())) {  
  112.                         _result = com.atp.aidl.Fruit.CREATOR.createFromParcel(_reply);  
  113.                     }  
  114.                     else {  
  115.                         _result = null;  
  116.                     }  
  117.                 }  
  118.                 finally {  
  119.                     _reply.recycle();  
  120.                     _data.recycle();  
  121.                 }  
  122.                 return _result;  
  123.             }  
  124.         }  
  125.         static final int TRANSACTION_getSomething = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);  
  126.         static final int TRANSACTION_getFruit = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);  
  127.     }  
  128.     public java.lang.String getSomething() throws android.os.RemoteException;  
  129.     public com.atp.aidl.Fruit getFruit() throws android.os.RemoteException;  
  130. }  

效果,点击之后获取service中的方法,返回所需的数据:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值