我正在尝试将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)
答案 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线程中的文件并读取您可以在新开始的活动中选择图像。