进程之间传递数据,由于Binder传递数据有限制1M,所以如果遇到大的数据传递的时候就需要使用使用到MemoryFile内存共享来解决,最合适不过了

首先,MemoryFile是基于Binder自带的transact方法进行传输数据的,因此直接继承Binder即可,不过一般项目中免不了传递一些基本数据类型或者bean数据,因此一般结合aidl一起使用。

android aidl使用记录

  • 服务端处理数据

    private byte[] buffer = new byte[1024];
	//public class MyBinder extends IRtcService.Stub {
    public class MyBinder extends Binder {
		//此方法Binder自带
        @Override
        public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
            LogUtil.e("接收到远端调用" + "code" + code);
            if (code == 100) {
                try {
                    ParcelFileDescriptor pfd = data.readParcelable(null);
                    // 或者
//                    ParcelFileDescriptor pfd = data.readFileDescriptor();
                    FileDescriptor fileDescriptor = pfd.getFileDescriptor();
                    FileInputStream fi = new FileInputStream(fileDescriptor);
                    fi.read(buffer);
                    fi.close();
                    LogUtil.e("--->" + new String(buffer).replace("\0", ""));

                    //返回给客户端
                    reply.writeString("服务器接受数据成功");
                    reply.writeInt(200);
                    return true;
                } catch (IOException e) {
                    e.printStackTrace();
                }


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

    }
  • 客户端

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
        try {
                /**
                 *
                 */
                // 参数1文件名,可为null,参数2文件长度
                mMemoryFile = new MemoryFile(null, 1024);
                //在设置了allowPurging为false之后,这个MemoryFile对应的Ashmem就会被标记成"pin",
                // 那么即使在android系统内存不足的时候,也不会对这段内存进行回收
                mMemoryFile.allowPurging(false);
                android.os.Parcel data = android.os.Parcel.obtain();
                android.os.Parcel reply = android.os.Parcel.obtain();

                byte[] buffer = "31283216382163812362183621832163812".getBytes();
                mMemoryFile.writeBytes(buffer, 0, 0, buffer.length);
                Method getFileDescriptorMethod = mMemoryFile.getClass().getDeclaredMethod("getFileDescriptor");
                if (getFileDescriptorMethod != null) {
                    FileDescriptor fileDescriptor = (FileDescriptor) getFileDescriptorMethod.invoke(mMemoryFile);
                    // 序列化,才可传送
                    ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(fileDescriptor);

                    //写入数据,对应服务端用data.readParcelable(null)接收数据
                    data.writeParcelable(pfd, 0);
                    // 或者,对应服务端用data.readFileDescriptor()接收数据
//                    data.writeFileDescriptor(fileDescriptor);
                    /**
                     * code 是一个整形的唯一标识,用于区分执行哪个方法,客户端会传递此参数,告诉服务端执行哪个方法;
                     * data客户端传递过来的参数;
                     * replay服务器返回回去的值;
                     * flags标明是否有返回值,0为有(双向),1为没有(单向)。
                     */
                    service.transact(100, data, reply, 0);

                    //服务器返回的值
                    String message = reply.readString();
                    LogUtil.e("--message--->" + message);
                    int code = reply.readInt();
                    LogUtil.e("--code--->" + code);
                    if (code==200){
                    	data.recycle();
                        reply.recycle();
                        mMemoryFile.close();
                        mMemoryFile=null;
                    }

                }


            } catch (RemoteException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            if (mConnection != null) {
                try {
                    iRtcService = null;
                    unbindService(mConnection);
                } catch (Exception e) {

                }
            }
        }
    };
  • 结果

    客户端

03-15 21:16:36.011 4327-4327/com.fuyao.elf_android_remote E/elf_remote: --message--->服务器接受数据成功
03-15 21:16:36.011 4327-4327/com.fuyao.elf_android_remote E/elf_remote: --code--->200

服务端

03-15 21:16:36.010 4300-4313/com.fuyao.elf_android_center:rtc_remote E/elf_center: 接收到远端调用code100
03-15 21:16:36.010 4300-4313/com.fuyao.elf_android_center:rtc_remote E/elf_center: --->31283216382163812362183621832163812
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐