MemoryFile匿名共享内存使用,android开发面试2024

package wzr.com.slidefinish.util;

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对象

*/

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;

}

}

ReflectUtil.java

package wzr.com.slidefinish.util;

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

/**

  • 反射工具类

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

}

/**

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后笔者收集整理了一份Flutter高级入门进阶资料PDF

以下是资料目录和内容部分截图



里面包括详细的知识点讲解分析,带你一个星期入门Flutter。还有130个进阶学习项目实战视频教程,让你秒变大前端。学不会来打我!

img-Nijq3WY2-1710845601387)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-kgqxBK1z-1710845601387)]

最后笔者收集整理了一份Flutter高级入门进阶资料PDF

以下是资料目录和内容部分截图

[外链图片转存中…(img-Fm7ALOX1-1710845601388)]
[外链图片转存中…(img-gI1podCY-1710845601388)]
里面包括详细的知识点讲解分析,带你一个星期入门Flutter。还有130个进阶学习项目实战视频教程,让你秒变大前端。学不会来打我!
[外链图片转存中…(img-0F92uOzv-1710845601388)]
以上资料皆无偿分享,领取方式:点击我的GitHub即可免费获取

内存映射是一种将文件映射到进程的内存空间的技术。内存映射可以通过将大文件映射到进程的虚拟地址空间,从而使得对文件的访问和操作变得更加高效。在处理超大文件读写时,内存映射(Memory Mapping)是一种常见的解决方案。 通过内存映射技术,文件可以直接映射到进程的内存空间中,从而避免了频繁的磁盘IO操作。当需要读取文件内容时,可以直接从内存中读取,而无需通过磁盘读取;当需要写入文件内容时,也可以直接在内存中进行写入,然后通过操作系统的缓存机制同步到磁盘中。这样一来,能够大大提高文件读写的效率。 内存映射超大文件的优势主要有以下几点: 1. 提高读写速度:内存映射利用了虚拟内存的机制,将磁盘文件映射到内存中,直接在内存中进行读写操作,不需要频繁的磁盘IO操作,因此能够提高读写速度。 2. 简化编程:内存映射将文件内容映射到进程的地址空间中,通过操作内存地址,可以直接访问文件内容,不需要手动进行文件的打开、关闭、读写等操作,简化了编程复杂度。 3. 节省内存空间:内存映射技术对文件进行了按需加载,只有当需要访问某一部分文件内容时,才将该部分内容加载到内存中。这种按需加载的方式避免了一次性将整个文件加载到内存中,节省了内存空间。 4. 方便并发操作:多个进程或线程可以通过共享内存映射的方式同时访问同一个文件,实现并发操作,提高了系统的并发性能。 然而,需要注意的是内存映射也有一些限制和风险,比如映射超大文件时可能会导致内存不足或虚拟内存紧张等问题。因此,在进行内存映射超大文件读写时,需要对文件的大小和内存资源进行合理评估和管理,确保系统的稳定性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值