服务 远程服务 AIDL 进程间通讯 IPC
Activity
aidl接口文件
package com.bqt.aidlservice;interface IBinderInterface {/* 更改文件后缀为【.aidl】去掉public等所有修饰符。更改后,会在gen目录下生成一个同名的.java文件,此java文件中有一个名为【Stub】的内部类,此内部类继承自Binder类且实现了我们这里定义的IBinderInterface接口此内部类的【asInterface(IBinder)】方法会将IBinder类型的对象转换成IBinderInterface接口类型,此内部类可以在进程间通讯*/void callMethodInService();}
自动生成的Java接口文件
/** This file is auto-generated. DO NOT MODIFY. Original file:* D:\\workspace_bqt\\Զ�̷���\\src\\com\\bqt\\aidlservice\\IBinderInterface.aidl*/package com.bqt.aidlservice;public interface IBinderInterface extends android.os.IInterface {/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements com.bqt.aidlservice.IBinderInterface {private static final java.lang.String DESCRIPTOR = "com.bqt.aidlservice.IBinderInterface";/** Construct the stub at attach it to the interface. */public Stub() {this.attachInterface(this, DESCRIPTOR);}/*** Cast an IBinder object into an com.bqt.aidlservice.IBinderInterface interface,* generating a proxy if needed.*/public static com.bqt.aidlservice.IBinderInterface asInterface(android.os.IBinder obj) {if ((obj == null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof com.bqt.aidlservice.IBinderInterface))) {return ((com.bqt.aidlservice.IBinderInterface) iin);}return new com.bqt.aidlservice.IBinderInterface.Stub.Proxy(obj);}@Overridepublic android.os.IBinder asBinder() {return this;}@Overridepublic boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {switch (code) {case INTERFACE_TRANSACTION: {reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_callMethodInService: {data.enforceInterface(DESCRIPTOR);this.callMethodInService();reply.writeNoException();return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.bqt.aidlservice.IBinderInterface {private android.os.IBinder mRemote;Proxy(android.os.IBinder remote) {mRemote = remote;}@Overridepublic android.os.IBinder asBinder() {return mRemote;}public java.lang.String getInterfaceDescriptor() {return DESCRIPTOR;}/** 更改文件后缀为.aidl,去掉public等所有修饰符。 更改后,会在gen/包名* 目录下生成一个同名的java文件,此java文件中有一个名为* 【Stub】的内部类,此内部类继承自Binder类且实现了我们这里定义的IBinderInterface接口* 此内部类的【asInterface* (IBinder)】方法会将IBinder类型的对象转换成IBinderInterface接口类型,此内部类可以在进程间通讯*/@Overridepublic void callMethodInService() throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);mRemote.transact(Stub.TRANSACTION_callMethodInService, _data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}}static final int TRANSACTION_callMethodInService = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}/** 更改文件后缀为.aidl,去掉public等所有修饰符。 更改后,会在gen/包名目录下生成一个同名的java文件* 此java文件中有一个名为【Stub】的内部类,此内部类继承自Binder类且实现了我们这里定义的IBinderInterface接口* 此内部类的【asInterface(IBinder)】方法会将IBinder类型的对象转换成IBinderInterface接口类型,此内部类可以在进程间通讯*/public void callMethodInService() throws android.os.RemoteException;}
远程Service
public class MyRemoteService extends Service {@Overridepublic void onCreate() {Log.i("bqt", "onCreate");super.onCreate();}@Overridepublic IBinder onBind(Intent intent) {//如果再次使用bindService绑定Service,系统不会再调用onBind()方法,而是直接把IBinder对象传递给其他后来增加的客户端Log.i("bqt", "onBind");return new MyBinder();//当访问者通过bindService方法与Service连接成功后,系统会将此返回的IBinder接口类型对象,通过bindService中的参数ServiceConnection对象的onServiceConnected方法,传递给访问者,访问者通过该对象便可以与Service组件进行通信}@Overridepublic void onRebind(Intent intent) {super.onRebind(intent);Log.i("bqt", "onRebind");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//客户端每次调用startService方法时都会回调此方法;调用bindService时不会回调此方法Log.i("bqt", "onStartCommand");return super.onStartCommand(intent, flags, startId);}@Overridepublic boolean onUnbind(Intent intent) {//绑定多客户端情况下,需要解除所有的绑定后才会(就会)调用onDestoryed方法,除非service也被startService()方法开启Log.i("bqt", "onUnbind");return super.onUnbind(intent);}@Overridepublic void onDestroy() {Log.i("bqt", "onDestroy");super.onDestroy();}//******************************************************************************************/**这是服务里面的一个方法,对外是隐藏的,只能通过IBinder间接访问*/private void methodInService() {Log.i("bqt", "服务里的方法被调用了……");// Toast.makeText(this, "服务里的方法被调用了……", Toast.LENGTH_SHORT).show();//弹土司会报异常 RuntimeException: Can't create handler inside thread that has not called Looper.prepare()}private class MyBinder extends IBinderInterface.Stub {//由【extends Binder implements IBinderInterface】改为【extends IBinderInterface.Stub】@Overridepublic void callMethodInService() throws RemoteException {methodInService();//间接调用了服务中的方法}}}
清单文件
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.bqt.aidlservice"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="21" /><!-- 声明权限 --><permissionandroid:name="com.bqt.permission"android:protectionLevel="normal" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name=".MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><!-- 指定激活此Service需要的权限 --><serviceandroid:name=".MyRemoteService"android:permission="com.bqt.permission" ><intent-filter><action android:name="com.bqt.service.REMOTE_SERVICE" /></intent-filter></service></application></manifest>
调用者Activity
public class MainActivity extends ListActivity {public static final String ACTION_REMOTE_SERVICE = "com.bqt.service.REMOTE_SERVICE";private MyServiceConnection conn;private IBinderInterface mIBinder;//之所以另外定义一个接口IBinderInterface,而不是直接用MyService.MyBinder,是为了使用统一接口访问,达到解耦、隐藏的目的@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);List<String> mData = new ArrayList<String>(Arrays.asList("startService方式开启服务", "stopService方式关闭服务", //"bindService方式开启服务 ", "unbindService方式解除绑定服务",//"startService启动服务后再bindService", "通过IBinder间接调用服务中的方法"));ListAdapter mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mData);setListAdapter(mAdapter);conn = new MyServiceConnection();}@Overrideprotected void onListItemClick(ListView l, View v, int position, long id) {Intent intent = new Intent(ACTION_REMOTE_SERVICE);switch (position) {case 0://startService方式开启服务。onCreate()--> onStartCommand() --->onDestory() 。onBind()方法并没有startService(intent);//当调用者结束了自己的生命周期,但是只要没调用stopService,那么Service还是会继续运行break;case 1://stopService方式关闭服务。service不建议采用隐式方式启动,在高版本可能警告"不安全",更高版本可能直接异常退出stopService(intent);//服务只会被停止一次,但多次调用并不会异常break;case 2://绑定的方式开启服务 onCreate() --->onBind();--->onUnbind()-->onDestory() 绑定服务不会调用onStartCommand方法bindService(intent, conn, BIND_AUTO_CREATE);//flags:绑定时如果Service还未创建是否自动创建;0:不自动创建;1:自动创建break;case 3:unbindService(conn);//多次调用会异常!mIBinder = null;//若不把mIBinder置为空,则服务销毁后仍然可以调用服务里的方法,因为内部类的引用还在break;case 4:startService(intent);//使用bindService来绑定一个【已启动】的Service时,系统只是将Service的内部IBinder对象传递给Activity,并不会将Service的生命周期与Activity绑定bindService(intent, conn, BIND_AUTO_CREATE);//所以,此时调用unBindService方法取消绑定后,Service不会调用onDestroy方法break;case 5:if (mIBinder != null) {try {mIBinder.callMethodInService();} catch (RemoteException e) {e.printStackTrace();}} else {Toast.makeText(this, "还没有绑定呦……", Toast.LENGTH_SHORT).show();}break;}}private class MyServiceConnection implements ServiceConnection {//Interface for monitoring监控 the state of an application service@Override/**此方法中的IBinder即为我们调用bindService方法时Service的onBind方法返回的对象,我们可以在此方法回调后通过这个IBinder与Service进行通信 */public void onServiceConnected(ComponentName name, IBinder service) {//访问者与Service连接成功时回调//Called when a connection连接 to the Service has been established确定、已建立, with the IBinder of the communication channel to the Service.mIBinder = IBinderInterface.Stub.asInterface(service);//回调方法中获得中间人时要调用IMiddlePerson.Stub.asInterface(service)方法。Toast.makeText(MainActivity.this, "服务已连接……", Toast.LENGTH_SHORT).show();}@Overridepublic void onServiceDisconnected(ComponentName name) {//异常终止或者其他原因终止导致Service与访问者断开连接时回调Toast.makeText(MainActivity.this, "服务已断开连接……", Toast.LENGTH_SHORT).show();}}}
调用者需拷贝远程服务的aidl文件
package com.bqt.aidlservice;interface IBinderInterface {//直接把服务中的此文件连同包名一起复制到调用者的src根目录中void callMethodInService();}
调用者清单文件
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.bqt.bindremote"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="17" /><!-- 声明使用指定的权限。一定要先【安装???】远程服务App再安装调用者App --><uses-permission android:name="com.bqt.permission" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name="com.bqt.bindremote.MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>
附件列表
服务 远程服务 AIDL 进程间通讯 IPC的更多相关文章
- 服务 远程服务 AIDL 进程间通讯 IPC 深化
示例 aidl接口文件 package com.bqt.aidlservice.aidl; parcelable Person; package com.bqt.aidlservice.aidl; ...
- Android AIDL 进行进程间通讯(IPC)
编写AIDL文件时,需要注意: 1.接口名和aidl文件名相同. 2.接口和方法前不用加访问权限修饰符 (public.private.protected等,也不能用final.static). 3. ...
- High Performance Networking in Google Chrome 进程间通讯(IPC) 多进程资源加载
小结: 1. 小文件存储于一个文件中: 在内部,磁盘缓存(disk cache)实现了它自己的一组数据结构, 它们被存储在一个单独的缓存目录里.其中有索引文件(在浏览器启动时加载到内存中),数据文件( ...
- QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开 本文地址:h ...
- 服务 进程间通讯 IPC AIDL Parcelable 简介
1.IBinder和Binder是什么鬼? 我们来看看官方文档怎么说: 中文翻译: IBinder是远程对象的基本接口,是为了高性能而设计的轻量级远程调用机制的核心部分. 但他不仅用于远程调用,也用 ...
- 进程间通讯IPC的几种方式总结
Linux进程间的通讯 Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同.前者对Unix早期的进程间通信 ...
- Python-互斥锁 进程间通讯
3.守护进程(**) 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常: AssertionError: daemonic proces ...
- Android(java)学习笔记232:Android进程间通讯(IPC)之AIDL
一.IPC inter process communication 进程间通讯 二.AIDL android interface defination language 安卓接口定义语言 满 ...
- Android(java)学习笔记175:Android进程间通讯(IPC)之AIDL
一.IPC inter process communication 进程间通讯 二.AIDL android interface defination language 安卓接口定义语言 满 ...
随机推荐
- 装饰(Decorator)模式
1.装饰(Decorator)模式 动态给一个对象添加一些额外的职责.就增加功能来说,装饰模式比生成子类更为灵活.Component是定义一个对象接口.可以给这些对象动态地添加职责.Concre ...
- 2.2 文件 I/O 的基石:Path
Path通常代表文件系统中的位置,能浏览任何类型的文件系统,包括zip归档文件系统: 文件系统中的几个概念:目录树.根目录.绝对路径.相对路径: NIO.2中的Path是一个抽象构造,你所创建和处理的 ...
- Android webview 应用
现在在android把一个网站打包成apk 是很简单的事,不懂一点代码的都可以去百度生成一个apk,app.当然样式就不是你所能控制的. 今天我就介绍一下 android 的 webview 在And ...
- python requests 基础学习
首先,Python 标准库中的 urllib2 模块提供了你所需要的大多数 HTTP 功能,但是它的 API 不友好.它是为另一个时代.另一个互联网所创建的.它需要巨量的工作,甚至包括各种方法覆盖,来 ...
- MAC OSX10.9.2上搭建Apache,php
mac osx10.9.* 自带了apache, php Apache配置 1- 启动 sudo apachectl start 启动后,访问 http://localhost/ 应该能看到" ...
- $(this).val()与this.value的区别?text()与html()的区别?
$(this).val()与this.value 作用:都是获得当前Dom对象的value值(一般是表单元素) text radio checkbox select 基本没有什么区别,只是: this ...
- LNMP笔记:域名重定向、读写权限、显示WP主题、北京时间
边写边记,以后还会用到的. 将 xxx.com 重定向到 www.xxx.com 1.打开 /usr/local/nginx/conf/vhost/你网站的域名.com.conf 2.查看原有的 se ...
- Python自动化运维之2、运算符与数据类型
python对象的相关术语: python程序中保存的所有数据都是围绕对象这个概念展开的: 程序中存储的所有数据都是对象 每个对象都有一个身份.一个类型和一个值 例如,school='MaGe Lin ...
- Swift—Cocoa Touch设计模式-备
目标(Target)与动作(Action)是iOS和OS X应用开发的中事件处理机制. 问题提出 如图所示是一个ButtonLabelSample案例设计原型图,其中包含一个标签和一个按钮,当点击 ...
- 转:全志A20 GPIO 总结文档
链接: http://blog.csdn.net/chwenj/article/details/42190745 /* * author: chwenj@gmail.com. * A ...

