Android跨进程通信的方式大概有如下几种:

1.Activity方式:

Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:12345678" ); startActivity(callIntent);

2.Content Provider 方式:

Android应用程序可以使用文件或SqlLite数据库来存储数据。Content Provider提供了一种在多个应用程序之间数据共享的方式(跨进程共享数据),应用程序可以利用Content Provider完成下面的工作1. 查询数据2. 修改数据3. 添加数据4. 删除数据

3.广播方式:

Intent intent = new Intent(“com.android.ACTION_TEST);intent.putExtra("value","content");mContext.sendBroadcast(intent);

4.LocalSocket方式

客户端LocalSocket代码//创建对象LocalSocket localSocket = new LocalSocket();//连接socketServerSocketlocalSocket.connect(new LocalSocketAddress(String addrStr));获取localSocket的输入输出流:outputStream = localSocket.getOutputStream();inputStream = localSocket.getInputStream();写入数据:outputStream.write("数据".getBytes());循环接收数据:try {          int readed = inputStream.read();      int size = 0;      byte[] bytes = new byte[0];      while (readed != -1) {          byte[] copy = new byte[500000];           System.arraycopy(bytes, 0, copy, 0, bytes.length);          bytes = copy;          bytes[size++] = (byte) readed;           //以换行符标识成结束          if ('\n' == (byte) readed) {              String resultStr = new String(bytes, 0, size);               break;                                                                      }        readed = inputStream.read();    }} catch (IOException e) {        return false;}服务端LocalServerSocket代码//初始化try {    //socketAddress需跟localSocket地址一致,否则无法连接上    serverSocket = new LocalServerSocket(socketAddress);} catch (IOException e) {    LoggerHelper.e("Server to establish connection exception:" + e.toString());    e.printStackTrace();    return false;}try {    //获取接收的LocalSocket    localSocket = serverSocket.accept();    //设置缓冲大小    localSocket.setReceiveBufferSize(ConstantConfig.BUFFER_SIZE);    localSocket.setSendBufferSize(ConstantConfig.BUFFER_SIZE);} catch (IOException e) {    e.printStackTrace();    LoggerHelper.d("Waiting to be linked to a bug,error:" + e.toString());    return false;}获取输入输出流一致:if (localSocket != null) {    try {        inputStream = localSocket.getInputStream();        outputStream = localSocket.getOutputStream();        /** 允许一直接收数据,一直到连接被断开,则认为应用端退出,自己也退出 */        while (isLock && receiveData()) ;    } catch (IOException e) {        LoggerHelper.e("Get stream exception:" + e.toString());        e.printStackTrace();        return false;    }}

5.AIDL Service方式

这也是本文采取的主要方式,通过AIDL读取共享内存的方式去实现大数据的传输
5.1首先定义两个AIDL文件,注意服务端和客户端的两个文件要一样,并且放在同一个文件夹下。

服务端使用package com.example.administrator.testgsensor;import com.example.administrator.testgsensor.ITestCallbackAidlInterface;// Declare any non-default types here with import statementsinterface ITestAidlInterface {    void registerCallback(ITestCallbackAidlInterface cb);    void unregisterCallback(ITestCallbackAidlInterface cb);    ParcelFileDescriptor getMemoryFileDescriptor();    void serverSendData(String data);}
客户端使用// ITestCallbackAidlInterface.aidlpackage com.example.administrator.testgsensor;// Declare any non-default types here with import statementsinterface ITestCallbackAidlInterface {     void clintSenddata(String data);}
服务端实现代码package com.example.administrator.testgsensor;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.MemoryFile;import android.os.ParcelFileDescriptor;import android.os.RemoteCallbackList;import android.os.RemoteException;import android.util.Log;import java.io.FileDescriptor;import java.io.IOException;import java.lang.reflect.Method;public class TestService extends Service{    private String TAG = "TestService";    private TestInterface mTestInterface = new TestInterface();    final RemoteCallbackList<ITestCallbackAidlInterface> mCallbackList = new RemoteCallbackList<ITestCallbackAidlInterface>();    private MemoryFile mMemoryFile = null;    private ParcelFileDescriptor pfd = null;    private boolean isRunFlag = false;    private FileDescriptor fd;    @Override    public void onCreate(){        super.onCreate();    }    @Override    public void onDestroy(){        super.onDestroy();    }    @Override    public IBinder onBind(Intent intent) {        isRunFlag = true;        return mTestInterface;    }    @Override    public void onStart(Intent intent, int startId){        super.onStart(intent, startId);    }    @Override    public boolean onUnbind(Intent intent){        isRunFlag = false;        if (mMemoryFile != null){            mMemoryFile.close();            mMemoryFile = null;        }        return super.onUnbind(intent);    }//实现接口ITestAidlInterface    public class TestInterface extends ITestAidlInterface.Stub {        @Override        public void registerCallback(ITestCallbackAidlInterface cb) throws RemoteException {            if(cb != null) mCallbackList.register(cb);        }        @Override        public void unregisterCallback(ITestCallbackAidlInterface cb) throws RemoteException {            if(cb != null) mCallbackList.unregister(cb);        }        @Override        public ParcelFileDescriptor getMemoryFileDescriptor() throws RemoteException {            if (pfd == null){                createMemoryFile();            }            if (pfd != null && !pfd.getFileDescriptor().valid()){                if (mMemoryFile != null){                    mMemoryFile.close();                    mMemoryFile = null;                }                try {                    pfd.close();                    pfd = null;                } catch (IOException e) {                    e.printStackTrace();                }                createMemoryFile();            }            return  pfd;        }        @Override        public void serverSendData(String data) throws RemoteException {            //客户端返回数据        }    }//创建共享内存块    private void createMemoryFile(){        if (mMemoryFile == null){            try {                mMemoryFile = new MemoryFile("memfile", 1000);                Method method = MemoryFile.class.getDeclaredMethod("getFileDescriptor");                fd = (FileDescriptor) method.invoke(mMemoryFile);                if (fd.valid()){                    Log.d(TAG, "createMemoryFile: fd valid");                    pfd = ParcelFileDescriptor.dup(fd);                    new Thread(testRunnable ).start();                }else {                    Log.e(TAG, "createMemoryFile: fd = -1");                }            } catch (Exception e) {                e.printStackTrace();                if (mMemoryFile != null){                    mMemoryFile.close();                    mMemoryFile = null;                }                pfd = null;            }        }    }    Runnable testRunnable = new Runnable() {        @Override        public void run() {            try {                while (isRunFlag){                    byte[] testData = {0x01,0x02,0x03};                    if (fd.valid()) {                    //往内存块里面写数据                        mMemoryFile.writeBytes(testData, 0, 0, testData.length);                    } else {                        writeStop();                    }                    Thread.sleep(10);                }                isRunFlag = false;            } catch (Exception e) {                e.printStackTrace();            } finally {                isRunFlag = false;            }        }    };//发送数据给客户端    private void writeStop() {        final int n = mCallbackList.beginBroadcast();        for (int i=0; i < n; i++) {            try {                mCallbackList.getBroadcastItem(i).clintSenddata("stop");            } catch (RemoteException e) {                e.printStackTrace();            }        }        mCallbackList.finishBroadcast();    }}记得在AndroidManifest.xml中注册service<service   android:name="com.example.administrator.testgsensor.TestService"   android:enabled="true"   android:exported="true">   <intent-filter >       <action android:name="com.example.administrator.testgsensor.TestService" />   </intent-filter></service>

接下来看客户端的代码

客户端代码package com.example.administrator.testgsensor;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.MemoryFile;import android.os.ParcelFileDescriptor;import android.os.RemoteException;import android.util.Log;import java.io.IOException;public class MainActivity extends Activity {    private static final String TAG = "MainActivity";    private boolean isBind = false;    private ITestAidlInterface mTestAidlInterface;    private MemoryFile mMemoryFile;    private boolean bRead = false;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        binderService();        bRead = true;        new Thread(new Runnable() {            @Override            public void run() {                byte[] data = new byte[3];                while (bRead){                    if (mTestAidlInterface != null && mMemoryFile != null) {                        try {                            //读取共享内存块的数据                            mMemoryFile.readBytes(data, 0, 0, data.length);                        } catch (IOException e) {                            e.printStackTrace();                        }                     }                }            }        }).start();            }    @Override    protected void onDestroy() {    if (mTestAidlInterface != null) {         try {             mTestAidlInterface.unregisterCallback(testCallbackAidlInterface);         } catch (RemoteException e) {             e.printStackTrace();         }    }    unBinderService();        super.onDestroy();    }    private ServiceConnection conn = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            if (mTestAidlInterface == null) {                mTestAidlInterface = ITestAidlInterface.Stub.asInterface(service);                Log.d(TAG, "onServiceConnected: ");                if (mTestAidlInterface != null) {                    try {                        mTestAidlInterface.registerCallback(testCallbackAidlInterface);                        //获取共享内存文件描述符                        ParcelFileDescriptor pfd = mTestAidlInterface.getMemoryFileDescriptor();                        if (pfd != null) {                            Log.d(TAG, "pfd != null "+pfd.toString());                            mMemoryFile = MemoryFileHelper.openMemoryFile(pfd, 1000, MemoryFileHelper.PROT_READ);                        }                    } catch (RemoteException e) {                        e.printStackTrace();                    }                }            }        }        @Override        public void onServiceDisconnected(ComponentName name) {            Log.d(TAG, "onServiceDisconnected: ");//正常情况下是不会被调用的,只有远程服务意外停止才会            unBinderService();        }    };    ITestCallbackAidlInterface testCallbackAidlInterface = new ITestCallbackAidlInterface.Stub() {        @Override        public void clintSenddata(String data) throws RemoteException {            //服务端发送数据        }    };    private void binderService() {        Intent intent = new Intent();        intent.setAction("com.example.administrator.testgsensor.TestService");        intent.setPackage("com.example.administrator.testgsensor");        intent.setClassName("com.example.administrator.testgsensor",                "com.example.administrator.testgsensor.TestService");        this.bindService(intent, conn, Context.BIND_AUTO_CREATE);        isBind = true;    }    private void unBinderService() {        if (isBind) {            this.unbindService(conn);            isBind = false;        }else {            return;        }        testCallbackAidlInterface = null;        if (mMemoryFile != null) {            mMemoryFile.close();            mMemoryFile = null;        }    }}

到此服务端和客户端的代码已经完成,两个进程间就可以通过读写共享内存块的方式共享大数据啦。
最后附上两个工具类的代码。

package com.example.administrator.testgsensor;import android.os.MemoryFile;import android.os.ParcelFileDescriptor;import android.util.Log;import java.io.FileDescriptor;import java.io.IOException;import java.lang.reflect.Method;public class MemoryFileHelper {    public static final int PROT_READ = 0x01;//只读方式打开,    public static final int PROT_WRITE = 0x02;//可写方式打开,PROT_WRITE|PROT_READ可读可写方式打开    private static final String TAG = "MemoryFileHelper";    /**     * 创建共享内存对象     *     * @param name   描述共享内存文件名称     * @param length 用于指定创建多大的共享内存对象     * @return MemoryFile 描述共享内存对象     */    public static MemoryFile createMemoryFile(String name, int length) {        try {            return new MemoryFile(name, length);        } catch (IOException e) {            e.printStackTrace();        }        return null;    }    public static MemoryFile openMemoryFile(ParcelFileDescriptor pfd, int length, int mode) {        if (pfd == null) {            throw new IllegalArgumentException("ParcelFileDescriptor 不能为空");        }        FileDescriptor fd = pfd.getFileDescriptor();        Log.d(TAG, "openMemoryFile: pfd="+pfd.toString());        Log.d(TAG, "openMemoryFile: fd="+fd.toString());        return openMemoryFile(fd, length, mode);    }    /**     * 打开共享内存,一般是一个地方创建了一块共享内存     * 另一个地方持有描述这块共享内存的文件描述符,调用     * 此方法即可获得一个描述那块共享内存的MemoryFile     * 对象     *     * @param fd     文件描述     * @param length 共享内存的大小     * @param mode   PROT_READ = 0x1只读方式打开,     *               PROT_WRITE = 0x2可写方式打开,     *               PROT_WRITE|PROT_READ可读可写方式打开     * @return MemoryFile     */    public static MemoryFile openMemoryFile(FileDescriptor fd, int length, int mode) {        MemoryFile memoryFile = null;        try {            memoryFile = new MemoryFile("tem", length);            memoryFile.close();            Class<?> c = MemoryFile.class;            Method native_mmap = null;            Method[] ms = c.getDeclaredMethods();            for (int i = 0; ms != null && i < ms.length; i++) {                if (ms[i].getName().equals("native_mmap")) {                    native_mmap = ms[i];                }            }            ReflectUtil.setField("android.os.MemoryFile", memoryFile, "mFD", fd);            ReflectUtil.setField("android.os.MemoryFile", memoryFile, "mLength", length);            //address 在4.4中是int类型,在6.0中是long类型。            long address = (Integer) ReflectUtil.invokeMethod(null, native_mmap, fd, length, mode);            ReflectUtil.setField("android.os.MemoryFile", memoryFile, "mAddress", address);            Log.d(TAG, "openMemoryFile: mFD"+fd.toString());            Log.d(TAG, "openMemoryFile: mLength"+length);            Log.d(TAG, "openMemoryFile: mAddress"+address);        } catch (Exception e) {            e.printStackTrace();        }        return memoryFile;    }    /**     * 获取memoryFile的ParcelFileDescriptor     *     * @param memoryFile 描述一块共享内存     * @return ParcelFileDescriptor     */    public static ParcelFileDescriptor getParcelFileDescriptor(MemoryFile memoryFile) {        if (memoryFile == null) {            throw new IllegalArgumentException("memoryFile 不能为空");        }        ParcelFileDescriptor pfd;        FileDescriptor fd = getFileDescriptor(memoryFile);        pfd = (ParcelFileDescriptor) ReflectUtil.getInstance("android.os.ParcelFileDescriptor", fd);        return pfd;    }    /**     * 获取memoryFile的FileDescriptor     *     * @param memoryFile 描述一块共享内存     * @return 这块共享内存对应的文件描述符     */    public static FileDescriptor getFileDescriptor(MemoryFile memoryFile) {        if (memoryFile == null) {            throw new IllegalArgumentException("memoryFile 不能为空");        }        FileDescriptor fd;        fd = (FileDescriptor) ReflectUtil.invoke("android.os.MemoryFile", memoryFile, "getFileDescriptor");        return fd;    }}
package com.example.administrator.testgsensor;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ReflectUtil {    /**     * 根据类名,参数实例化对象     *     * @param className 类的路径全名     * @param params    构造函数需要的参数     * @return 返回T类型的一个对象     */    public static Object getInstance(String className, Object... params) {        if (className == null || className.equals("")) {            throw new IllegalArgumentException("className 不能为空");        }        try {            Class<?> c = Class.forName(className);            if (params != null) {                int plength = params.length;                Class[] paramsTypes = new Class[plength];                for (int i = 0; i < plength; i++) {                    paramsTypes[i] = params[i].getClass();                }                Constructor constructor = c.getDeclaredConstructor(paramsTypes);                constructor.setAccessible(true);                return constructor.newInstance(params);            }            Constructor constructor = c.getDeclaredConstructor();            constructor.setAccessible(true);            return constructor.newInstance();        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    /**     * 执行instance的方法     *     * @param className  类的全名     * @param instance   对应的对象,为null时执行类的静态方法     * @param methodName 方法名称     * @param params     参数     */    public static Object invoke(String className, Object instance, String methodName, Object... params) {        if (className == null || className.equals("")) {            throw new IllegalArgumentException("className 不能为空");        }        if (methodName == null || methodName.equals("")) {            throw new IllegalArgumentException("methodName不能为空");        }        try {            Class<?> c = Class.forName(className);            if (params != null) {                int plength = params.length;                Class[] paramsTypes = new Class[plength];                for (int i = 0; i < plength; i++) {                    paramsTypes[i] = params[i].getClass();                }                Method method = c.getDeclaredMethod(methodName, paramsTypes);                method.setAccessible(true);                return method.invoke(instance, params);            }            Method method = c.getDeclaredMethod(methodName);            method.setAccessible(true);            return method.invoke(instance);        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    /**     * 执行指定的对方法     *     * @param instance 需要执行该方法的对象,为空时,执行静态方法     * @param m        需要执行的方法对象     * @param params   方法对应的参数     * @return 方法m执行的返回值     */    public static Object invokeMethod(Object instance, Method m, Object... params) {        if (m == null) {            throw new IllegalArgumentException("method 不能为空");        }        m.setAccessible(true);        try {            return m.invoke(instance, params);        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    /**     * 取得属性值     *     * @param className 类的全名     * @param fieldName 属性名     * @param instance  对应的对象,为null时取静态变量     * @return 属性对应的值     */    public static Object getField(String className, Object instance, String fieldName) {        if (className == null || className.equals("")) {            throw new IllegalArgumentException("className 不能为空");        }        if (fieldName == null || fieldName.equals("")) {            throw new IllegalArgumentException("fieldName 不能为空");        }        try {            Class c = Class.forName(className);            Field field = c.getDeclaredField(fieldName);            field.setAccessible(true);            return field.get(instance);        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    /**     * 设置属性     *     * @param className 类的全名     * @param fieldName 属性名     * @param instance  对应的对象,为null时改变的是静态变量     * @param value     值     */    public static void setField(String className, Object instance, String fieldName, Object value) {        if (className == null || className.equals("")) {            throw new IllegalArgumentException("className 不能为空");        }        if (fieldName == null || fieldName.equals("")) {            throw new IllegalArgumentException("fieldName 不能为空");        }        try {            Class<?> c = Class.forName(className);            Field field = c.getDeclaredField(fieldName);            field.setAccessible(true);            field.set(instance, value);        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 根据方法名,类名,参数获取方法     *     * @param className  类名,全名称     * @param methodName 方法名     * @param paramsType 参数类型列表     * @return 方法对象     */    public static Method getMethod(String className, String methodName, Class... paramsType) {        if (className == null || className.equals("")) {            throw new IllegalArgumentException("className 不能为空");        }        if (methodName == null || methodName.equals("")) {            throw new IllegalArgumentException("methodName不能为空");        }        try {            Class<?> c = Class.forName(className);            return c.getDeclaredMethod(methodName, paramsType);        } catch (Exception e) {            e.printStackTrace();        }        return null;    }}

更多相关文章

  1. Android(安卓)7.1 根据4G共享动态调整以太网优先级
  2. android 之摄像头
  3. Android在内存中读取数据
  4. 【Android】_MyContentProvider_外部访问接口
  5. android中的数据库操作
  6. 仿Android6.0联系人列表
  7. android前端怎样php后台交互(基础篇)
  8. Android中ContentProvider详解
  9. Android(安卓)音频 OpenSL ES PCM数据播放

随机推荐

  1. Shell脚本高效检测主机存活
  2. 分布式链路追踪 SkyWalking 源码分析 —
  3. 分布式链路追踪 SkyWalking 源码分析 —
  4. 分布式链路追踪 SkyWalking 源码分析 —
  5. 阿里最新开源配置中心和注册中心: Nacos
  6. 分布式链路追踪 SkyWalking 源码分析 —
  7. 分布式链路追踪 SkyWalking 源码分析 —
  8. 分享一个牛逼的阿里天猫面经,已经拿到 Off
  9. Node.js 中的ES模块现状[每日前端夜话0x8
  10. 一张 JVM 相关的思维脑图(4.4M)