在(通过意图)在byteArray中传递(通过意图)jpg图像文件时,而不是在传递png图像文件

时间:2018-07-13 01:04:44

标签: android image android-intent start-activity

我正在尝试将jpg和png图像文件从一个活动(ImageUploadActivity)发送到另一个活动(ImageResultActivity)。该图像是从图库中选择的,或者是从相机中拍摄的。

//Select image from gallery
//belongs to ImageUploadActivity

Bitmap bm = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImage);
File file = new File("testPic.png");
FileOutputStream fos = openFileOutput("testPic.png" , 0);
bm.compress(Bitmap.CompressFormat.PNG, 50 , fos);
fos.flush();
fos.close();

下面是我尝试有意发送图像的代码行。 当我传递PNG格式时,它工作得很好,但是由于startActivity(),它大约以JPG格式返回RuntimeError。我将这段代码放在Handler中,因为在开始新活动之前,我需要显示一小段时间。

//belongs to ImageUploadActivity's one button's clicklistener

new Handler().postDelayed(new Runnable() {
    @Override public void run() {
        ByteArrayOutputStream bStream = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 50, bStream);
        byte[] byteArray = bStream.toByteArray();
        Intent i = new Intent(ImageUploadActivity.this,ImageResultActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        i.putExtra("imageArrInput", byteArray);
        startActivity(i);
    }
}, 1500);

这是完整的错误跟踪

07-13 10:10:00.075 3731-3749/? E/JavaBinder: !!! FAILED BINDER TRANSACTION !!!  (parcel size = 76)
07-13 10:10:02.254 15346-15346/example.com.samsung.humintec E/aaaa: [B@20377d1
        i.putExtra("imageArrInput", byteArray);
    Stream.flush();
    bStream.close();
07-13 10:10:02.261 15346-15346/example.com.samsung.humintec E/JavaBinder: !!! FAILED BINDER TRANSACTION !!!  (parcel size = 4512136)
07-13 10:10:02.267 15346-15346/example.com.samsung.humintec E/AndroidRuntime: FATAL EXCEPTION: main
        Process: example.com.samsung.humintec, PID: 15346
        java.lang.RuntimeException: Failure from system
            at android.app.Instrumentation.execStartActivity(Instrumentation.java:1533)
            at android.app.Activity.startActivityForResult(Activity.java:4399)
            at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
            at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:65)
            at android.app.Activity.startActivityForResult(Activity.java:4358)
            at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:711)
            at android.app.Activity.startActivity(Activity.java:4682)
            at android.app.Activity.startActivity(Activity.java:4650)
            at example.com.samsung.humintec.Activity.ImageUploadActivity$2.run(ImageUploadActivity.java:119)
            at android.os.Handler.handleCallback(Handler.java:751)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:154)
            at android.app.ActivityThread.main(ActivityThread.java:6682)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
         Caused by: android.os.TransactionTooLargeException: data parcel size 4512136 bytes
            at android.os.BinderProxy.transactNative(Native Method)
            at android.os.BinderProxy.transact(Binder.java:628)
            at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3529)
            at android.app.Instrumentation.execStartActivity(Instrumentation.java:1526)
            at android.app.Activity.startActivityForResult(Activity.java:4399) 
            at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54) 
            at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:65) 
            at android.app.Activity.startActivityForResult(Activity.java:4358) 
            at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:711) 
            at android.app.Activity.startActivity(Activity.java:4682) 
            at android.app.Activity.startActivity(Activity.java:4650) 
            at example.com.samsung.humintec.Activity.ImageUploadActivity$2.run(ImageUploadActivity.java:119) 
            at android.os.Handler.handleCallback(Handler.java:751) 
            at android.os.Handler.dispatchMessage(Handler.java:95) 
            at android.os.Looper.loop(Looper.java:154) 
            at android.app.ActivityThread.main(ActivityThread.java:6682) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410) 

2 个答案:

答案 0 :(得分:1)

您有一个TransactionTooLargeException

  

避免TransactionTooLargeException的关键是保留所有   交易比较少。尽量减少内存量   需要为参数和返回值创建一个包裹   远程过程调用。避免传输大量的字符串   或大型位图。如果可能,请尝试将大请求分解为   小块。

或者您可以在here

中看到更多内容

我不知道您为什么需要通过意图传递它,因为您可以在第二次活动中获得它。

所以我的解决方案是仅发送一个密钥(可能是该图像的名称),并在第二个活动中(使用该密钥)将其获取,如下所示:

发送密钥

new Handler().postDelayed(new Runnable() {
                @Override public void run() {
                    i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                    i.putExtra("image_name", yourImageName);
                    startActivity(i);
                }
            }, 1500);

在第二个活动中:

Bitmap bmp = null;
String filename = getIntent().getStringExtra("image_name");
try {
    FileInputStream is = this.openFileInput(filename);
    bmp = BitmapFactory.decodeStream(is);
    is.close();
} catch (Exception e) {
    e.printStackTrace();
}

希望这会有所帮助

答案 1 :(得分:0)

Intent不适合传递大型对象,因为Intent会序列化和反序列化对象,这对于大型对象而言并不容易。

如果您的项目使用EventBus,则可以通过EventBus传递图像对象,因为EventBus仅传递对象的引用。

如果您不想使用EventBus或想要进行进程间传递(EventBus不能这样做),则可以使用@GianhTran的方式,即将图像另存为非ui线程中的文件并读取您可以在新开始的活动中选择图像。