`
guoyu04
  • 浏览: 7189 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

android AIDL 编程Demo

阅读更多
一, AIDL 用来做什么?
进程之间的通讯
问题:有其他方式可以进行进程之间的通讯,为什么要用aidl
比如,两个进程之间,可以通过互相发送intent来实现通讯,但是具有局限性
问题:什么局限性
当有一个公共服务需要发布时,如何相互发送intent,一个服务需要应付各种各样的(n个)客户端时,随时有新的客户端来调用这个服务。 此时已经无能为力了!
解决:
把自己的服务当成一个接口公布出去!不管谁调用都不用管!双方按一定的规矩来办事就可以。
AIDL就是来做这事的!

做个例子看是最清晰了,我用了两工程,一个专门是service , 一个是调用的 activity:


二,服务端该如何动手?
好,一步一步来
1,aidl文件
这是个接口描述文件
ICommonService.aidl

package org.guoyu.service; 
import org.guoyu.service.Data; 

interface ICommonService{ 
boolean addStr(String str); 
void addData(in Data data); 
Data getData(); 
} 

build一下工程,这可以使用eclipse,能生成ICommonService.java 文件
2,为这个公共接口做个实现。
RemoteService.java

public class RemoteService extends Service { 
private static final String TAG = "RemoteService"; 
private Data data; 
@Override 
public IBinder onBind(Intent arg0) { 
Log.i(TAG, "onBind"); 
return mBinder; 
} 

private ICommonService.Stub mBinder = new ICommonService.Stub() { 
@Override 
public boolean addStr(String str) throws RemoteException { 
Log.i(TAG,"add String :"+ str); 
return add(str); 
} 

@Override 
public void addData(Data data) throws RemoteException { 
Log.i(TAG,"add Data :"+ data); 
setData(data); 
} 

@Override 
public Data getData() throws RemoteException { 
if(data == null) 
data = new Data("Test" ,; 
return data; 
} 
}; 

@SuppressWarnings("unused") 
private boolean add(final String str){ 
if("ok".equals(str)) 
return true; 
else 
return false; 
} 
public void setData(Data data) { 
this.data = data; 
} 
} 

3,传输类的描述文件编写(上面有一个Data类,在进程之间是不能进行传输的,如果要传输的基本数据类型,String,CharSequence ,就无需3,4步骤,直接跳过)
Data.aidl
package org.guoyu.service; 

parcelable Data; 


4,传输类实体文件编写
Data.java
package org.guoyu.service; 

import android.os.Parcel; 
import android.os.Parcelable; 

public class Data implements Parcelable { 
//------ 
//1 
public Data(Parcel source){ 
name = source.readString(); 
type = source.readInt(); 
} 
//2 
public static final Parcelable.Creator<Data> CREATOR = new Parcelable.Creator<Data>() { 
@Override 
public Data createFromParcel(Parcel source) { 
return new Data(source); 
} 

@Override 
public Data[] newArray(int size) { 
return new Data[size]; 
} 

}; 
//3 
@Override 
public int describeContents() { 
return 0; 
} 
@Override 
public void writeToParcel(Parcel dest, int flags) { 
dest.writeString(name); 
dest.writeInt(type); 
} 
//---------- 



private String name; 
private int type; 
public Data(){ 
} 
public Data(String name ,int type){ 
this.name = name; 
this.type = type; 
} 
... 
} 

5,service需要被远程调用,需要在xml文件中配置一下:然后给加上个action ,以便去调用
<service android:name=".RemoteService" android:process=":remote"> 
<intent-filter> 
<action android:name="org.guoyu.service.RemoteService"></action> 
</intent-filter> 
</service> 


=================服务器端算是完成了,那么客户端该做些什么呢?
客户端:
6,同样的,客户端也需要拥有这些aidl文件,然后还有Data对象,copy到客户端的工程下
7,首先是要获取一个远程对象的代理
在需要调用的类中,(我用的是activity)加入两个属性:
private ICommonService mRemoteSerivce; 
private ServiceConnection mRemoteConnection = new ServiceConnection(){ 
@Override 
public void onServiceConnected(ComponentName className, IBinder service) { 
mRemoteSerivce = ICommonService.Stub.asInterface(service); 
} 
@Override 
public void onServiceDisconnected(ComponentName arg0) { 
mRemoteSerivce = null; 
} 
}; 

8,让其连接对象能与我们相应的服务对得上号。本人是放在onCreate中
public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        。。。。 
        bindService(new Intent("org.guoyu.service.RemoteService"), 
        mRemoteConnection , 
        Context.BIND_AUTO_CREATE); 
    } 

9,然后找个触发事件去调用即可
10,千万别忘了在activity退出的时候需要把连接给闭上噢
@Override 
    public void onDestroy(){ 
    unbindService(mRemoteConnection); 
    super.onDestroy(); 
    } 


如有问题,请写在下面
代码我放在附件中了!eclipse project
2
0
分享到:
评论
2 楼 abcdeudi 2015-12-16  
  
写得真不错!
1 楼 wzq83045309 2012-09-04  

相关推荐

Global site tag (gtag.js) - Google Analytics