下面列出了怎么用android.os.MemoryFile的API类实例代码及写法,或者点击链接到github查看源代码。
public static ParcelFileDescriptor getParcelFileDescriptor(MemoryFile file) throws IOException {
try {
Method method = MemoryFile.class.getDeclaredMethod("getFileDescriptor");
FileDescriptor fileDescriptor = (FileDescriptor) method.invoke(file);
Field field = fileDescriptor.getClass().getDeclaredField("descriptor");
field.setAccessible(true);
int fd = field.getInt(fileDescriptor);
return ParcelFileDescriptor.adoptFd(fd);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | NoSuchFieldException e) {
throw new IOException(e);
}
}
private ParcelFileDescriptor getParcelStreamForAttachment(MasterSecret masterSecret, AttachmentId attachmentId) throws IOException {
AttachmentRepo repo = Repository.getAttachmentRepo(AMELogin.INSTANCE.getMajorContext());
if (repo == null) {
ALog.w(TAG, "AttachmentRepo is null!");
return null;
}
InputStream stream = repo.getAttachmentStream(masterSecret, attachmentId.getRowId(), attachmentId.getUniqueId(), 0);
if (stream == null) {
throw new FileNotFoundException("Attachment file not found");
}
long plaintextLength = Util.getStreamLength(stream);
MemoryFile memoryFile = new MemoryFile(attachmentId.toString(), Util.toIntExact(plaintextLength));
InputStream in = repo.getAttachmentStream(masterSecret, attachmentId.getRowId(), attachmentId.getUniqueId(), 0);
OutputStream out = memoryFile.getOutputStream();
Util.copy(in, out);
Util.close(out);
Util.close(in);
return MemoryFileUtil.getParcelFileDescriptor(memoryFile);
}
private ParcelFileDescriptor getGroupStreamForAttachment(MasterSecret masterSecret, long gid, long indexId) throws IOException {
InputStream stream = MessageDataManager.INSTANCE.getFileStream(masterSecret.getAccountContext(), masterSecret, gid, indexId, 0);
if (stream == null) {
throw new FileNotFoundException("Attachment file not found");
}
long plaintextLength = Util.getStreamLength(stream);
MemoryFile memoryFile = new MemoryFile("(gid: " + gid + ", index id: " + indexId + ")", Util.toIntExact(plaintextLength));
InputStream in = MessageDataManager.INSTANCE.getFileStream(masterSecret.getAccountContext(), masterSecret, gid, indexId, 0);
OutputStream out = memoryFile.getOutputStream();
Util.copy(in, out);
Util.close(out);
Util.close(in);
return MemoryFileUtil.getParcelFileDescriptor(memoryFile);
}
public static void init(Context context) {
if (sFonts != null) {
return;
}
sCache = new LruCache<String, MemoryFile>(FontProviderSettings.getMaxCache()) {
@Override
protected void entryRemoved(boolean evicted, String key, MemoryFile oldValue, MemoryFile newValue) {
if (evicted) {
oldValue.close();
}
}
@Override
protected int sizeOf(String key, MemoryFile value) {
return value.length();
}
};
sFonts = new ArrayList<>();
for (int res : FONTS_RES) {
FontInfo font = new Gson().fromJson(new InputStreamReader(context.getResources().openRawResource(res)), FontInfo.class);
sFonts.add(font);
}
}
private Bitmap decodeFileDescriptorAsPurgeable(
CloseableReference<PooledByteBuffer> bytesRef,
int inputLength,
byte[] suffix,
BitmapFactory.Options options) {
MemoryFile memoryFile = null;
try {
memoryFile = copyToMemoryFile(bytesRef, inputLength, suffix);
FileDescriptor fd = getMemoryFileDescriptor(memoryFile);
if (mWebpBitmapFactory != null) {
Bitmap bitmap = mWebpBitmapFactory.decodeFileDescriptor(fd, null, options);
return Preconditions.checkNotNull(bitmap, "BitmapFactory returned null");
} else {
throw new IllegalStateException("WebpBitmapFactory is null");
}
} catch (IOException e) {
throw Throwables.propagate(e);
} finally {
if (memoryFile != null) {
memoryFile.close();
}
}
}
private ParcelFileDescriptor getParcelStreamForAttachment(AttachmentId attachmentId) throws IOException {
long plaintextLength = Util.getStreamLength(DatabaseFactory.getAttachmentDatabase(getContext()).getAttachmentStream(attachmentId, 0));
MemoryFile memoryFile = new MemoryFile(attachmentId.toString(), Util.toIntExact(plaintextLength));
InputStream in = DatabaseFactory.getAttachmentDatabase(getContext()).getAttachmentStream(attachmentId, 0);
OutputStream out = memoryFile.getOutputStream();
Util.copy(in, out);
Util.close(out);
Util.close(in);
return MemoryFileUtil.getParcelFileDescriptor(memoryFile);
}
private ParcelFileDescriptor getPfd(MemoryFile file) {
try {
if (!file.getFileDescriptor().valid()) {
throw new IllegalStateException("Invalid file descriptor");
}
return new ParcelFileDescriptor(file.getFileDescriptor());
} catch (IOException ex) {
throw new IllegalStateException("Failed to get PFD from memory file", ex);
}
}
ActiveBuffer(IGraphicsStatsCallback token, int uid, int pid, String packageName,
long versionCode)
throws RemoteException, IOException {
mInfo = new BufferInfo(packageName, versionCode, System.currentTimeMillis());
mUid = uid;
mPid = pid;
mCallback = token;
mToken = mCallback.asBinder();
mToken.linkToDeath(this, 0);
mProcessBuffer = new MemoryFile("GFXStats-" + pid, ASHMEM_SIZE);
mProcessBuffer.writeBytes(ZERO_DATA, 0, 0, ASHMEM_SIZE);
}
/**
* This function encode handle information in {@link android.os.MemoryFile} into a long array to
* be passed down to native methods.
*
* @hide */
static long[] encodeData(MemoryFile ashmem) {
int fd;
try {
fd = ashmem.getFileDescriptor().getInt$();
} catch (IOException e) {
fd = -1;
}
return new long[] { 1 /*numFds*/, 0 /*numInts*/, fd };
}
public static FileDescriptor getFileDescriptor(MemoryFile mf) {
if (getFileDescriptorMethod != null) {
try {
return (FileDescriptor) getFileDescriptorMethod.invoke(mf);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
return null;
}
private MemoryFile getMemoryFile(String path) {
try {
byte[] data = ByteStreams.toByteArray(getTestImageInputStream(path));
MemoryFile memoryFile = new MemoryFile(null, data.length);
memoryFile.allowPurging(false);
memoryFile.writeBytes(data, 0, 0, data.length);
return memoryFile;
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
private synchronized Method getFileDescriptorMethod() {
if (sGetFileDescriptorMethod == null) {
try {
sGetFileDescriptorMethod = MemoryFile.class.getDeclaredMethod("getFileDescriptor");
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
return sGetFileDescriptorMethod;
}
private FileDescriptor getMemoryFileDescriptor(MemoryFile memoryFile) {
try {
Object rawFD = getFileDescriptorMethod().invoke(memoryFile);
return (FileDescriptor) rawFD;
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
@Test
public void test_webp_extended_decoding_filedescriptor_bitmap() throws Throwable {
final MemoryFile memoryFile = getMemoryFile("webp_e.webp");
final Bitmap bitmap =
mWebpBitmapFactory.decodeFileDescriptor(getMemoryFileDescriptor(memoryFile), null, null);
memoryFile.close();
assertBitmap(bitmap, 480, 320);
}
@Test
public void test_webp_extended_with_alpha_decoding_filedescriptor_bitmap() throws Throwable {
final MemoryFile memoryFile = getMemoryFile("webp_ea.webp");
final Bitmap bitmap =
mWebpBitmapFactory.decodeFileDescriptor(getMemoryFileDescriptor(memoryFile), null, null);
memoryFile.close();
assertBitmap(bitmap, 400, 301);
}
@Test
public void test_webp_lossless_decoding_filedescriptor_bitmap() throws Throwable {
final MemoryFile memoryFile = getMemoryFile("webp_ll.webp");
final Bitmap bitmap =
mWebpBitmapFactory.decodeFileDescriptor(getMemoryFileDescriptor(memoryFile), null, null);
memoryFile.close();
assertBitmap(bitmap, 400, 301);
}
@Test
public void test_webp_plain_decoding_filedescriptor_bitmap() throws Throwable {
final MemoryFile memoryFile = getMemoryFile("webp_plain.webp");
final Bitmap bitmap =
mWebpBitmapFactory.decodeFileDescriptor(getMemoryFileDescriptor(memoryFile), null, null);
memoryFile.close();
assertBitmap(bitmap, 320, 214);
}
private synchronized Method getFileDescriptorMethod() {
if (sGetFileDescriptorMethod == null) {
try {
sGetFileDescriptorMethod = MemoryFile.class.getDeclaredMethod("getFileDescriptor");
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
return sGetFileDescriptorMethod;
}
private FileDescriptor getMemoryFileDescriptor(MemoryFile memoryFile) {
try {
Object rawFD = getFileDescriptorMethod().invoke(memoryFile);
return (FileDescriptor) rawFD;
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
/**
* 创建指定大小的共享内存区域
*
* @param capacity 共享内存大小,单位字节
* @throws IOException
*/
public MemoryFileCache(int capacity) throws IOException {
if (capacity < 0) {
throw new IllegalArgumentException("MemoryCache init capacity can't less than zero!!!");
}
memoryFile = new MemoryFile(String.valueOf(System.currentTimeMillis()), capacity);
memoryFile.allowPurging(false);// 不允许被清除,防止写入数据丢失
BDebug.d(TAG, "MemoryFileCache() capacity:" + memoryFile.length());
}
/** @hide */
protected abstract SensorDirectChannel createDirectChannelImpl(
MemoryFile memoryFile, HardwareBuffer hardwareBuffer);
/** @hide */
protected SensorDirectChannel createDirectChannelImpl(
MemoryFile memoryFile, HardwareBuffer hardwareBuffer) {
int id;
int type;
long size;
if (memoryFile != null) {
int fd;
try {
fd = memoryFile.getFileDescriptor().getInt$();
} catch (IOException e) {
throw new IllegalArgumentException("MemoryFile object is not valid");
}
if (memoryFile.length() < MIN_DIRECT_CHANNEL_BUFFER_SIZE) {
throw new IllegalArgumentException(
"Size of MemoryFile has to be greater than "
+ MIN_DIRECT_CHANNEL_BUFFER_SIZE);
}
size = memoryFile.length();
id = nativeCreateDirectChannel(
mNativeInstance, size, SensorDirectChannel.TYPE_MEMORY_FILE, fd, null);
if (id <= 0) {
throw new UncheckedIOException(
new IOException("create MemoryFile direct channel failed " + id));
}
type = SensorDirectChannel.TYPE_MEMORY_FILE;
} else if (hardwareBuffer != null) {
if (hardwareBuffer.getFormat() != HardwareBuffer.BLOB) {
throw new IllegalArgumentException("Format of HardwareBuffer must be BLOB");
}
if (hardwareBuffer.getHeight() != 1) {
throw new IllegalArgumentException("Height of HardwareBuffer must be 1");
}
if (hardwareBuffer.getWidth() < MIN_DIRECT_CHANNEL_BUFFER_SIZE) {
throw new IllegalArgumentException(
"Width if HaradwareBuffer must be greater than "
+ MIN_DIRECT_CHANNEL_BUFFER_SIZE);
}
if ((hardwareBuffer.getUsage() & HardwareBuffer.USAGE_SENSOR_DIRECT_DATA) == 0) {
throw new IllegalArgumentException(
"HardwareBuffer must set usage flag USAGE_SENSOR_DIRECT_DATA");
}
size = hardwareBuffer.getWidth();
id = nativeCreateDirectChannel(
mNativeInstance, size, SensorDirectChannel.TYPE_HARDWARE_BUFFER,
-1, hardwareBuffer);
if (id <= 0) {
throw new UncheckedIOException(
new IOException("create HardwareBuffer direct channel failed " + id));
}
type = SensorDirectChannel.TYPE_HARDWARE_BUFFER;
} else {
throw new NullPointerException("shared memory object cannot be null");
}
return new SensorDirectChannel(this, id, type, size);
}
public static void safeClose(MemoryFile mf) {
if (mf != null) {
mf.close();
}
}
public static FileDescriptor getFileDescriptor(Context context, String filename) {
MemoryFile mf = sCache.get(filename);
if (mf != null) {
Log.i(TAG, "MemoryFile " + filename + " is in the cache");
FileDescriptor fd = MemoryFileUtils.getFileDescriptor(mf);
if (fd != null && fd.valid()) {
return fd;
} else {
Log.i(TAG, "MemoryFile " + filename + " is not valid?");
}
}
long time = System.currentTimeMillis();
Log.i(TAG, "loading file " + filename);
// built in font? read from asset
if (BUILT_IN_FONTS_SIZE.containsKey(filename)) {
mf = MemoryFileUtils.fromAsset(context.getAssets(), filename, FILE_SIZE.get(filename));
}
// downloadable font? read from file
if (mf == null) {
File file = ContextUtils.getExternalFile(context, filename);
if (file.exists()) {
mf = MemoryFileUtils.fromFile(file);
if (mf != null) {
FILE_SIZE.put(filename, mf.length());
}
}
}
// file not exist?
if (mf == null) {
Log.w(TAG, "loading " + filename + " failed");
return null;
}
Log.i(TAG, "loading finished in " + (System.currentTimeMillis() - time) + "ms");
sCache.put(filename, mf);
return MemoryFileUtils.getFileDescriptor(mf);
}
/**
* Create a sensor direct channel backed by shared memory wrapped in MemoryFile object.
*
* The resulting channel can be used for delivering sensor events to native code, other
* processes, GPU/DSP or other co-processors without CPU intervention. This is the recommanded
* for high performance sensor applications that use high sensor rates (e.g. greater than 200Hz)
* and cares about sensor event latency.
*
* Use the returned {@link android.hardware.SensorDirectChannel} object to configure direct
* report of sensor events. After use, call {@link android.hardware.SensorDirectChannel#close()}
* to free up resource in sensor system associated with the direct channel.
*
* @param mem A {@link android.os.MemoryFile} shared memory object.
* @return A {@link android.hardware.SensorDirectChannel} object.
* @throws NullPointerException when mem is null.
* @throws UncheckedIOException if not able to create channel.
* @see SensorDirectChannel#close()
* @see #configureDirectChannel(SensorDirectChannel, Sensor, int)
*/
public SensorDirectChannel createDirectChannel(MemoryFile mem) {
return createDirectChannelImpl(mem, null);
}
/**
* Allocates a new ashmem region. The region is initially not purgable.
*
* @param name optional name for the file (can be null).
* @param frameSize how many frame to store
* @param length of the memory file in bytes.
* @throws IOException if the memory file could not be created.
*/
public SharedVideoMemory(String name, int frameSize, int length) throws IOException {
mSharedMemFile = new MemoryFile(name, length);
mFrameSize = frameSize;
}