服务 远程服务 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);

        }

        @Override

        public android.os.IBinder asBinder() {

            return this;

        }

        @Override

        public 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;

            }

            @Override

            public 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接口类型,此内部类可以在进程间通讯

             */

            @Override

            public 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 {

    @Override

    public void onCreate() {

        Log.i("bqt", "onCreate");

        super.onCreate();

    }

    @Override

    public IBinder onBind(Intent intent) {//如果再次使用bindService绑定Service,系统不会再调用onBind()方法,而是直接把IBinder对象传递给其他后来增加的客户端

        Log.i("bqt", "onBind");

        return new MyBinder();//当访问者通过bindService方法与Service连接成功后,系统会将此返回的IBinder接口类型对象,通过bindService中的参数ServiceConnection对象的onServiceConnected方法,传递给访问者,访问者通过该对象便可以与Service组件进行通信

    }

    @Override

    public void onRebind(Intent intent) {

        super.onRebind(intent);

        Log.i("bqt", "onRebind");

    }

    @Override

    public int onStartCommand(Intent intent, int flags, int startId) {//客户端每次调用startService方法时都会回调此方法;调用bindService时不会回调此方法

        Log.i("bqt", "onStartCommand");

        return super.onStartCommand(intent, flags, startId);

    }

    @Override

    public boolean onUnbind(Intent intent) {//绑定多客户端情况下,需要解除所有的绑定后才会(就会)调用onDestoryed方法,除非service也被startService()方法开启

        Log.i("bqt", "onUnbind");

        return super.onUnbind(intent);

    }

    @Override

    public 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】

        @Override

        public 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-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="21" />

    <!-- 声明权限 -->

    <permission

        android:name="com.bqt.permission"

        android:protectionLevel="normal" />

    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android: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需要的权限 -->

        <service

            android: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,是为了使用统一接口访问,达到解耦、隐藏的目的

    @Override

    protected 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();

    }

    @Override

    protected 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();

        }

        @Override

        public 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-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="17" />

    <!-- 声明使用指定的权限。一定要先【安装???】远程服务App再安装调用者App -->

    <uses-permission android:name="com.bqt.permission" />

    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android: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>

来自为知笔记(Wiz)

附件列表

时间: 2024-12-28 15:56:39

服务 远程服务 AIDL 进程间通讯 IPC的相关文章

服务 远程服务 AIDL 进程间通讯 IPC 深化

示例 aidl接口文件 package com.bqt.aidlservice.aidl; parcelable Person;  package com.bqt.aidlservice.aidl; parcelable Salary;   package com.bqt.aidlservice.aidl; import com.bqt.aidlservice.aidl.Salary;   import com.bqt.aidlservice.aidl.Person; interface IBi

Android AIDL 进行进程间通讯(IPC)

编写AIDL文件时,需要注意: 1.接口名和aidl文件名相同. 2.接口和方法前不用加访问权限修饰符 (public.private.protected等,也不能用final.static). 3.AIDL默认支持的类型包括java基本类型 (int.long.boolean等) 和 (String.List.Map.CharSequence),使用这些类型时不需要import声明.对于List和Map中的元素类型必须是AIDL支持的类型,如果使用自定义类型作为参数或者返回值,自定义类型必须实

进程间通讯IPC的几种方式的优缺点总结

Linux进程间的通讯 Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同.前者对Unix早期的进程间通信手段进行了系统的改进和扩充,形成了"system V IPC",通信进程局限在单个计算机内:后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制.Linux则把两者继承了下来,如图示: 管道 管道的通信介质是文件,这种文件通常称为管道文件,两个进程利用管道文件进行通信时,一

Android进阶笔记04:Android进程间通讯之Messenger ( 区别于AIDL)

一. Android进程间通讯之Messenger 的引入 (1)引言:      平时一说进程间通讯,大家都会想到AIDL,其实messenger和AIDL作用一样,都可以进行进程间通讯.它是基于消息的进程间通信,就像子线程和UI线程发送消息那样,是不是很简单,还不用去写AIDL文件,是不是有点小爽.哈哈.此外,还支持记录客户端对象的Messenger,然后可以实现一对多的通信:甚至作为一个转接处,任意两个进程都能通过服务端进行通信. (2) Messenger 与 AIDL 比较:    

【IPC进程间通讯之一】邮槽MailSlot

IPC进程间通信+邮槽MailSlot         IPC(Inter-Process Communication,进程间通信).        现代计算机采用虚拟内存机制,为进程提供独立的足够大的地址空间,处于安全目的,一个进程不具有特殊的权限,是无法访问另一个进程的内存空间,进程间相互隔绝.进程间通信IPC就需要特别的机制来实现,邮槽MailSlot是常用的IPC方法之一.                 1.邮槽(MailSlot):                 邮槽MailSlo

【IPC进程间通讯之二】管道Pipe

IPC进程间通信+管道Pipe         IPC(Inter-Process Communication,进程间通信).         管道用于进程间共享数据,其实质是共享内存,常用IPC之一.管道不仅可以用于本机进程间通信,还可实现跨网络进程间通信,如同Socket通信,管道同样封装计算机底层网络实现,提供一个良好的API接口.                1.管道(Pipe):        管道分为匿名管道和命名管道.        匿名管道只能用于父子进程间通信 ,不能跨网络通

linux进程间通讯-System V IPC 信号量

进程间通信的机制--信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信--使用信号.下面就进入信号量的讲解. 一.什么是信号量 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域.临界区域是指执行数据更新的代码需要独占式地执行.而信号量就可以提供这样的一种访问机制,让一个临界区同一时间只有一个线程在

UNIX 进程间通讯(IPC)概念(Posix,System V IPC)

 IPC(Inter-Process Communication,进程间通讯)可以有三种信息共享方式(随文件系统,随内核,随共享内存).(当然这里虽然说是进程间通讯,其实也是可以和线程相通的). 相对的IPC的持续性(Persistence of IPC Object)也有三种: 随进程持续的(Process-Persistent IPC) IPC对象一直存在,直到最后拥有他的进程被关闭为止,典型的IPC有pipes(管道)和FIFOs(先进先出对象) 随内核持续的(Kernel-persist

进程间通讯aidl

进程间通讯(aidl) 1.首先定义一个接口 2.把这个接口的文件扩展名改为xxx.aidl 3.写一个MyService类继承自Service类重新里面的方法, 4.在MyService类定义一个内部类继承自Stub类 5.在onBind()方法把内部类的一个实例作为返回值同外部访问 6.在MainActivity中通过bindService(intent,ServiceConnection,flag)方法中的第二个参数他是一个接口,要一个类继承或者通过匿名对象作为参数 它里面有两个方法onS