服务 远程服务 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 IBinderInterface {      void callMethodInService();            String queryPerson(int num);          //定义一个Person对象作为传入参数。接口中定义方法时,需要制定新参的传递模式,这里是传入,所以前面有一个【in】     Salary getMsg(in Person owner);   }

Bean1


package com.bqt.aidlservice.aidl;

import android.os.Parcel;

import android.os.Parcelable;

public class Person implements Parcelable {

    public String name;

    public Person(String name) {

        this.name = name;

    }

    @Override

    public int hashCode() {

        return name.hashCode();

    }

    @Override

    public boolean equals(Object o) {

        if (o instanceof Person) {

            return name.equals(((Person) o).name);

        } else {

            return false;

        }

    }

    @Override     public int describeContents() { //实现Parcelable必须实现的方法,不知道拿来干嘛的,直接返回0就行了         return 0;     }     @Override     public void writeToParcel(Parcel dest, int flags) { //把对象所包含的数据写入到parcel中         dest.writeString(name);//可以write各种类型的数据     }     //必须提供一个名为【CREATOR】的static final属性,该属性需要实现android.os.Parcelable.Creator<T>接口     public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {         @Override         public Person createFromParcel(Parcel source) {             return new Person(source.readString());//从Parcel中读取数据,返回Person对象,和构造方法中的参数列表相对应         }         @Override         public Person[] newArray(int size) {             return new Person[size];         }     }; }

Bean2


package com.bqt.aidlservice.aidl;

import android.os.Parcel;

import android.os.Parcelable;

public class Salary implements Parcelable {

    public String type;

    public Integer salary;

    public Salary(String type, Integer salary) {

        this.type = type;

        this.salary = salary;

    }

    public String toString() {

        return "工作:" + type + "    薪水: " + salary;

    }

    @Override     public int describeContents() {         return 0;     }     @Override     public void writeToParcel(Parcel dest, int flags) {         dest.writeString(type);         dest.writeInt(salary);     }     public static final Parcelable.Creator<Salary> CREATOR = new Parcelable.Creator<Salary>() {         //从Parcel中读取数据,返回Person对象         @Override         public Salary createFromParcel(Parcel source) {             return new Salary(source.readString(), source.readInt());         }         @Override         public Salary[] newArray(int size) {             return new Salary[size];         }     }; }

自动生成的Java接口文件


/*

 * This file is auto-generated. DO NOT MODIFY. Original file:

 * D:\\workspace_bqt\\

 * ??????\\src\\com\\bqt\\aidlservice\\aidl\\IBinderInterface.aidl

 */

package com.bqt.aidlservice.aidl;

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.aidl.IBinderInterface {

        private static final java.lang.String DESCRIPTOR = "com.bqt.aidlservice.aidl.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.aidl.IBinderInterface interface,

         * generating a proxy if needed.

         */

        public static com.bqt.aidlservice.aidl.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.aidl.IBinderInterface))) {

                return ((com.bqt.aidlservice.aidl.IBinderInterface) iin);

            }

            return new com.bqt.aidlservice.aidl.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;

            }

            case TRANSACTION_queryPerson: {

                data.enforceInterface(DESCRIPTOR);

                int _arg0;

                _arg0 = data.readInt();

                java.lang.String _result = this.queryPerson(_arg0);

                reply.writeNoException();

                reply.writeString(_result);

                return true;

            }

            case TRANSACTION_getMsg: {

                data.enforceInterface(DESCRIPTOR);

                com.bqt.aidlservice.aidl.Person _arg0;

                if ((0 != data.readInt())) {

                    _arg0 = com.bqt.aidlservice.aidl.Person.CREATOR.createFromParcel(data);

                } else {

                    _arg0 = null;

                }

                com.bqt.aidlservice.aidl.Salary _result = this.getMsg(_arg0);

                reply.writeNoException();

                if ((_result != null)) {

                    reply.writeInt(1);

                    _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);

                } else {

                    reply.writeInt(0);

                }

                return true;

            }

            }

            return super.onTransact(code, data, reply, flags);

        }

        private static class Proxy implements com.bqt.aidlservice.aidl.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;

            }

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

                }

            }

            @Override

            public java.lang.String queryPerson(int num) throws android.os.RemoteException {

                android.os.Parcel _data = android.os.Parcel.obtain();

                android.os.Parcel _reply = android.os.Parcel.obtain();

                java.lang.String _result;

                try {

                    _data.writeInterfaceToken(DESCRIPTOR);

                    _data.writeInt(num);

                    mRemote.transact(Stub.TRANSACTION_queryPerson, _data, _reply, 0);

                    _reply.readException();

                    _result = _reply.readString();

                } finally {

                    _reply.recycle();

                    _data.recycle();

                }

                return _result;

            }

            //定义一个Person对象作为传入参数。接口中定义方法时,需要制定新参的传递模式,这里是传入,所以前面有一个【in】

            @Override

            public com.bqt.aidlservice.aidl.Salary getMsg(com.bqt.aidlservice.aidl.Person owner) throws android.os.RemoteException {

                android.os.Parcel _data = android.os.Parcel.obtain();

                android.os.Parcel _reply = android.os.Parcel.obtain();

                com.bqt.aidlservice.aidl.Salary _result;

                try {

                    _data.writeInterfaceToken(DESCRIPTOR);

                    if ((owner != null)) {

                        _data.writeInt(1);

                        owner.writeToParcel(_data, 0);

                    } else {

                        _data.writeInt(0);

                    }

                    mRemote.transact(Stub.TRANSACTION_getMsg, _data, _reply, 0);

                    _reply.readException();

                    if ((0 != _reply.readInt())) {

                        _result = com.bqt.aidlservice.aidl.Salary.CREATOR.createFromParcel(_reply);

                    } else {

                        _result = null;

                    }

                } finally {

                    _reply.recycle();

                    _data.recycle();

                }

                return _result;

            }

        }

        static final int TRANSACTION_callMethodInService = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);

        static final int TRANSACTION_queryPerson = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);

        static final int TRANSACTION_getMsg = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);

    }

    public void callMethodInService() throws android.os.RemoteException;

    public java.lang.String queryPerson(int num) throws android.os.RemoteException;

    //定义一个Person对象作为传入参数。接口中定义方法时,需要制定新参的传递模式,这里是传入,所以前面有一个【in】

    public com.bqt.aidlservice.aidl.Salary getMsg(com.bqt.aidlservice.aidl.Person owner) throws android.os.RemoteException;

}

远程Service


public class MyRemoteService extends Service {

    private String[] names = { "B神", "艹神", "基神", "J神", "翔神" };

    private static Map<Person, Salary> map = new HashMap<Person, Salary>();

    static {

        map.put(new Person("包青天"), new Salary("码农", 20000));

        map.put(new Person("白乾涛"), new Salary("歌手", 1000));

        map.put(new Person("baiqiantao"), new Salary("学生", 50));

        map.put(new Person("bqt"), new Salary("老师", 8000));

    }

    @Override

    public IBinder onBind(Intent intent) {

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

        return new MyBinder();

    }

    /**无参无返回值的方法*/     private void methodInService() {         Log.i("bqt", "服务里的方法被调用了……");     }     /**基本类型有返回值方法*/     private String query(int num) {         if (num >= 0 && num < 5) {             return names[num];         }         return "尼玛,只能传0-4";     }     /**传递复杂数据*/     private Salary getPersonSalary(Person person) throws RemoteException {         Salary salary = map.get(person);//对于Hash系列的集合,是先判断对象的【hashCode】返回值是否相同,再判断对象的【equals】返回值是否为true         if (salary != null) {             return salary;         } else {             return new Salary("木有工作", 0);         }     }
    private class MyBinder extends Stub {//不是由【extends Binder implements IBinderInterface】改为【extends IBinderInterface.Stub】而是改为【extends Stub】         @Override         public void callMethodInService() throws RemoteException {             methodInService();         }         @Override         public String queryPerson(int num) throws RemoteException {             return query(num);         }         @Override         public Salary getMsg(Person person) throws RemoteException {             return getPersonSalary(person);         }     } }

清单文件


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

    public static final String[] personNames = { "包青天", "白乾涛", "baiqiantao", "bqt", "O(∩_∩)O哈哈~" };

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        List<String> mData = new ArrayList<String>(Arrays.asList("bindService绑定服务", "unbindService取消绑定服务"//

                , "调用无参无返回值的方法", "调用基本类型有返回值方法", "传递复杂数据"));

        setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mData));

        conn = new MyServiceConnection();

    }

    @Override

    protected void onListItemClick(ListView l, View v, int position, long id) {

        if (position == 0) {

            bindService(new Intent(ACTION_REMOTE_SERVICE), conn, BIND_AUTO_CREATE);

        } else if (position == 1) {

            unbindService(conn);

            mIBinder = null;

        } else {

            if (mIBinder == null) {

                Toast.makeText(this, "还没绑定呦", Toast.LENGTH_SHORT).show();

                return;

            }

            try {

                switch (position) {

                case 2:

                    mIBinder.callMethodInService();

                    break;

                case 3:

                    Toast.makeText(this, "查询结果为:" + mIBinder.queryPerson(new Random().nextInt(6)), Toast.LENGTH_SHORT).show();

                    break;

                case 4:

                    Toast.makeText(this, mIBinder.getMsg(new Person(personNames[new Random().nextInt(5)])).toString(), Toast.LENGTH_SHORT).show();

                    break;

                }

            } catch (RemoteException e) {

                e.printStackTrace();

            }

        }

    }

    private class MyServiceConnection implements ServiceConnection {

        @Override

        public void onServiceConnected(ComponentName name, IBinder service) {

            mIBinder = IBinderInterface.Stub.asInterface(service);

            Toast.makeText(MainActivity.this, "服务已连接", Toast.LENGTH_SHORT).show();

        }

        @Override

        public void onServiceDisconnected(ComponentName name) {

        }

    }

}

调用者清单文件


<?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" />

    <!-- 声明使用指定的权限 -->

    <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-10-24 15:35:07

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

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

Activity aidl接口文件 package com.bqt.aidlservice;  interface IBinderInterface {     /* 更改文件后缀为[.aidl]去掉public等所有修饰符.         更改后,会在gen目录下生成一个同名的.java文件,此java文件中有一个名为[Stub]的内部类,此内部类继承自Binder类且实现了我们这里定义的IBinderInterface接口         此内部类的[asInterface(IBinder

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