应用之间的通信Aidl和共享内存块MemoryFile的使用
来源:互联网 发布:python难找工作 编辑:程序博客网 时间:2024/06/05 23:00
前天经理交给我一个任务,需求是在一个应用中获取摄像头的数据传递到另外一个应用中使用,生成图片。原理是运用android进程之间的通信AIDL技术,传递分辨率,图片的格式N21,摄像头传递的每一帧的图片大小都是固定的,计算方式为宽*高*单位像素字节,把每一帧图片放入共享内存,在客户端中读取共享内存数据,那么怎么保证一边写一边读,读完之后在写,写完之后在读,这样一步一步进行呢,用锁机制肯定是不行的,因为这属于不同进程了,经理牛人告诉我,用内存中第一位做标志位,默认为0代表可以写,1代表可以读,这样相互标志位的变化,就保障了流程的运行,最后在拿到摄像头数据之后,怎么把它显示出来呢,直接上代码
YuvImage yuvImage = new YuvImage(readdata, ImageFormat.NV21, 1920, 1080,null);
//YuvImage yuvImage = new YuvImage(mBufferBean.mBuffer, ImageFormat.NV21, 1280, 720, null);// MyLog.d(TAG, "readShareBufferMsg yuvImage:" + yuvImage);if (yuvImage != null) {
stream = new ByteArrayOutputStream();
yuvImage.compressToJpeg(new Rect(0, 0, 1920, 1080), 80, stream);
bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
stream.close();
}
通过自带的YuvImage类,可以转换成bitmap显示出来。
如何操作MemoryFile呢,上代码
/** * Created by ethanzhang on 2017/5/10.*/
import android.os.MemoryFile;
import android.os.ParcelFileDescriptor;
import java.io.FileDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
/** * 对memoryFile类的扩展* 1.从memoryFile对象中获取FileDescriptor,ParcelFileDescriptor* 2.根据一个FileDescriptor和文件length实例化memoryFile对象* Created by wuzr on 2016/7/16. */public class 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();
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", 1);
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);
long address = (long) ReflectUtil.invokeMethod(null, native_mmap, fd, length, mode);
ReflectUtil.setField("android.os.MemoryFile", memoryFile,"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.newsmy.stream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/** * Created by ethanzhang on 2017/5/10.*/
/** * 反射工具类* Created by wuzr on 2016/6/27. */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;
}
}
怎么写入标志位:
while (mStartVideo &&mMemoryFile != null) {
//读取第一个字节,为0可以写,为1可以读 byte[] buffer=new byte[1];
try {
mMemoryFile.readBytes(buffer,0,0,1);
if(buffer[0]==0)
{
if(YUVQueue.size()>0)
{
mMemoryFile.writeBytes(new byte[]{1},0,0,1);
byte[] input=YUVQueue.poll();
try {
mMemoryFile.writeBytes(input,0,1,input.length);
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
阅读全文
0 0
- 应用之间的通信Aidl和共享内存块MemoryFile的使用
- Ashmem、MemoryFile、Binder的共享内存(jni可用)
- AIDL解析(一)两个应用之间使用AIDL进行通信的例子
- Android匿名共享内存和MemoryFile
- Android匿名共享内存和MemoryFile
- Android匿名共享内存和MemoryFile
- 进程之间的通信 ------内存共享
- 进程之间的通信方式-共享内存
- 进程之间的通信AIDL
- aidl进程之间的通信
- 驱动与应用层之间的共享内存通信与事件通知
- Android 使用AIDL实现进程之间的通信(一)
- 进程之间使用共享内存通信....
- Linux C编程--进程间通信(IPC)6--综合应用实例--信号量和共享内存的使用
- Linux C编程--进程间通信(IPC)6--综合应用实例--信号量和共享内存的使用
- Android:AIDL进程之间的通信
- Android AIDL 进程之间的通信
- Aidl实现应用程序之间的 通信
- 监督学习(supervised learning)和无监督学习(unsupervised learning)
- opencv for ios 配置后#import <opencv2/opencv.hpp>报错:file not found问题(opencv3.2.0)
- C++实现R语言向量化运算(向量类:c 矩阵类:matrix)2015.9.11
- PE文件格式学习笔记
- 3DTouch
- 应用之间的通信Aidl和共享内存块MemoryFile的使用
- 仿iOS滚轮选择控
- socket客户端与服务端消息互发
- 接口和抽象类
- JavaWeb学习十一(JSTL标签库)
- SSH中的jar包讲解
- 使用阿里云的短信服务发送短信验证码
- NDK 编译
- Telink之UART篇