Android Service学习之AIDL, Parcelable和远程服务
通过代码来实现这个数据传输过程是冗长乏味的,Android提供了AIDL工具来处理这项工作。
AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。
- Calls made from the local process are executed in the same thread that is making the call. If this is your main UI thread, that thread continues to execute in the AIDL interface. If it is another thread, that is the one that executes your code in the service. Thus, if only local threads are accessing the service, you can completely control which threads are executing in it (but if that is the case, then you shouldn't be using AIDL at all, but should instead create the interface byimplementing a Binder).
- Calls from a remote process are dispatched from a thread pool the platform maintains inside of your own process. You must be prepared for incoming calls from unknown threads, with multiple calls happening at the same time. In other words, an implementation of an AIDL interface must be completely thread-safe.
- The
onewaykeyword modifies the behavior of remote calls. When used, a remote call does not block; it simply sends the transaction data and immediately returns. The implementation of the interface eventually receives this as a regular call from theBinderthread pool as a normal remote call. Ifonewayis used with a local call, there is no impact and the call is still synchronous.
AIDL使用简单的语法来声明接口,描述其方法以及方法的参数和返回值。这些参数和返回值可以是任何类型,甚至是其他AIDL生成的接口。
需要特别注意的是,对于非基本数据类型,也不是String和CharSequence类型的,需要有方向指示,包括in、out和inout,in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。
import com.demo.Person;
interface IMyService {
void savePersonInfo(in Person person);
List<Person> getAllPerson();
}
private LinkedList<Person> personList = new LinkedList<Person>();
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IMyService.Stub mBinder = new IMyService.Stub(){
@Override
public void savePersonInfo(Person person) throws RemoteException {
if (person != null){
personList.add(person);
}
}
@Override
public List<Person> getAllPerson() throws RemoteException {
return personList;
}
};
}
public static abstract class Stub extends android.os.Binder implements com.demo.IMyService
1) void writeToParcel(Parcel dest, int flags) 将需要序列化存储的数据写入外部提供的Parcel对象dest。而看了网上的代码例子,个人猜测,读取Parcel数据的次序要和这里的write次序一致,否则可能会读错数据。具体情况我没试验过!
2) describeContents() 没搞懂有什么用,反正直接返回0也可以
3) static final Parcelable.Creator对象CREATOR 这个CREATOR命名是固定的,而它对应的接口有两个方法:
createFromParcel(Parcel source) 实现从source创建出JavaBean实例的功能
newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话(return new T[size])即可。估计本方法是供外部类反序列化本类数组使用。
private String name;
private String telNumber;
private int age;
public Person() {}
public Person(Parcel pl){
name = pl.readString();
telNumber = pl.readString();
age = pl.readInt();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTelNumber() {
return telNumber;
}
public void setTelNumber(String telNumber) {
this.telNumber = telNumber;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(telNumber);
dest.writeInt(age);
}
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
return new Person(source);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
parcelable Person;
3. 抛出的异常是不能返回给调用者(跨进程抛异常处理是不可取的)。
3. 客户端获取接口
private ServiceConnection mRemoteConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mRemoteService = IMyService.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName className) {
mRemoteService = null;
}
};
* Cast an IBinder object into an com.demo.IMyService interface,
* generating a proxy if needed.
*/
public static com.demo.IMyService asInterface(android.os.IBinder obj) {...}
unbindService(mRemoteConnection);
}else{
bindService(new Intent("com.demo.IMyService"),
mRemoteConnection, Context.BIND_AUTO_CREATE);
}
mIsRemoteBound = !mIsRemoteBound;
new View.OnClickListener(){
private int index = 0;
@Override
public void onClick(View view) {
Person person = new Person();
index = index + 1;
person.setName("Person" + index);
person.setAge(20);
person.setTelNumber("123456");
try {
mRemoteService.savePersonInfo(person);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
listPersonButton.setOnClickListener(
new View.OnClickListener(){
@Override
public void onClick(View view) {
List<Person> list = null;
try {
list = mRemoteService.getAllPerson();
} catch (RemoteException e) {
e.printStackTrace();
}
if (list != null){
StringBuilder text = new StringBuilder();
for(Person person : list){
text.append("\nPerson name:");
text.append(person.getName());
text.append("\n age :");
text.append(person.getAge());
text.append("\n tel number:");
text.append(person.getTelNumber());
}
inputPersonEdit.setText(text);
}else {
Toast.makeText(ServiceActivity.this, "get data error",
Toast.LENGTH_SHORT).show();
}
}
});
如果Service在AndroidManifest.xml中声明了全局的强制的访问权限,其他引用必须声明权限才能来start,stop或bind这个service.
另外,service可以通过权限来保护她的IPC方法调用,通过调用checkCallingPermission(String)方法来确保可以执行这个操作。
<intent-filter>
<action android:name="com.demo.IMyService" />
</intent-filter>
</service>
The name of the process where the service is to run. Normally, all components of an application run in the default process created for the application. It has the same name as the application package. The <application> element's process attribute can set a different default for all components. But component can override the default with its own process attribute, allowing you to spread your application across multiple processes.
也就是说android:process=":remote",代表在应用程序里,当需要该service时,会自动创建新的进程。而如果是android:process="remote",没有“:”分号的,则创建全局进程,不同的应用程序共享该进程。
Android Service学习之AIDL, Parcelable和远程服务的更多相关文章
- Android 中的AIDL,Parcelable和远程服务
Android 中的AIDL,Parcelable和远程服务 早期在学习期间便接触到AIDL,当时对此的运用也是一撇而过.只到近日在项目中接触到AIDL,才开始仔细深入.AIDL的作用 ...
- Android Service学习
Android 中的 Service 全面总结 引用别人的博客:http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html 好文章 1.S ...
- android Service 学习总结
学习android开发已经四五个月,由于项目中职责的原因一直没有接触过Service的实际项目,今天重新学一遍Service用法. 问题: 作为四大组件,为什么需要Service? 它与Thread又 ...
- Android Service学习之本地服务
Service是在一段不定的时间运行在后台,不和用户交互应用组件.每个Service必须在manifest中 通过来声明.可以通过contect.startservice和contect.bindse ...
- Android Service学习之IntentService 深入分析
什么是IntentService? (本文转自http://blog.csdn.net/gaojie314/archive/2010/11/28/6040701.aspx) 官方的解释是: ...
- android service 学习
参考:http://www.cnblogs.com/allin/archive/2010/05/15/1736458.html http://www.cnblogs.com/allin/archive ...
- 从零开始学android -- Service
废话不多说了,Service是四大组件之一,是一个后台处理长时间运行在主线程不需要依赖ui界面显示的应用组件,切记不能在service中做耗时操作,会阻塞主线程,要做也要在service中开个子线程做 ...
- android service 本地 远程 总结
android编写Service入门 android SDK提供了Service,用于类似*nix守护进程或者windows的服务. Service有两种类型: 本地服务(Local Service) ...
- android Service Activity三种交互方式(付源码)
android SDK提供了Service,用于类似Linix守护进程或者windows的服务. Service有两种类型: 本地服务(Local Service):用于应用程序内部 远程服务(Rem ...
随机推荐
- T-SQL DBMS
dbo 默认架构schema 从一个数据库操作另个数据库的表的时候,要select * from 数据库.dbo.biao 表名前面的dbo是一个默认架构schema,一个架构还有 ...
- 采用HSV生成随机颜色
使用hsv/hsb生成随机颜色,并排除靠近黑白两色的色值 public static String randomColor(){ int max = 25500000 ; Random rand = ...
- Alamofire数据请求
let stringurl = "http://www.huiyunche.cn/kyleuat/banner/list" Alamofire.request(.GET,strin ...
- 总结android项目的基本开发步骤(转帖)
总结android项目的基本开发步骤(转帖) 做了几个android企业应用项目后,总结了项目的基本开发步骤,希望能够交流.一 应用规划: ※确定功能. ※必须的界面及界面跳转的流程. ...
- Linux常用命令-入门
linux 开源安全性高 linux 和 windows 1.同时登陆多用户 2.安全 3.linux没有盘符的概念 /. / root 根目录 4.linux的文件没有扩展名 ...
- smoke
1.Have a smoke? 2.Would you like a cigarette? 3.Cigarettes? 4.Let's go have a smoke. 5.Do you smoke ...
- GenderGuesser
http://www.hackerfactor.com/GenderGuesser.php#Analyze
- Python - KMP算法
def kmp_match(tex, pat): n = len(tex) m = len(pat) tex = '0' + tex pat = '0' + pat pi = [] pi.append ...
- jq窗口类小问题
if ($(window).height() + $(window).scrollTop() >= $(document.body).height() - options.marginBotto ...
- [troubleshoot][archlinux][X] plasma(KDE) 窗口滚动刷新冻结(约延迟10s)(已解决,root cause不明,无法再次复现)
现象: konsole,setting等plasma的系统应用反应缓慢,在滚动条滚动时,尤为明显. 触发条件: 并不是十分明确的系统滚动升级(Syu)后,产生. 现象收集: 可疑的dmesg [ :: ...