android 使用ParcelFileDescriptor跨进程传递大图

1,418 阅读1分钟
public class ParcelFileDescriptorUtil {

    /**
     * bitmap转ParcelFileDescriptor
     * @param bitmap bitmap
     * @return ParcelFileDescriptor
     */
    public static ParcelFileDescriptor convertToPFD(Bitmap bitmap) {
        if (bitmap == null) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        byte[] bitmapData = baos.toByteArray();
        try {
            MemoryFile imageMemoryFile = new MemoryFile("captured_image", bitmapData.length);
            imageMemoryFile.writeBytes(bitmapData, 0, 0, bitmapData.length);
            FileDescriptor imageFileDescriptor = (FileDescriptor) invoke("android.os.MemoryFile",
                    imageMemoryFile, "getFileDescriptor");
            return ParcelFileDescriptor.dup(imageFileDescriptor);
        } catch (IOException exception) {
            exception.printStackTrace();
            return null;
        }
    }

    /**
     * ParcelFileDescriptor转bitmap
     * @param pfd pfd
     * @return bitmap
     */
    @MainThread
    public static Bitmap toBitmap(ParcelFileDescriptor pfd) {
        if (pfd == null) {
            return null;
        }
        return BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
    }

    /**
     * 执行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;
    }
}