如何将包含位图的对象传递给另一个活动 [英] How to pass object which contain Bitmap to another activity
问题描述
所以我是Android开发中的新手,我试图制作一个注册活动(UserPrivateInfoSignUpActivity.java
),该活动加载图片(位图)并创建一个我想传递给另一个活动的UserPersona
对象(UserGeneralDataSignUpActivity
).
so I am kind of new in Android Developing, I was trying to make a Sign-up Activity (UserPrivateInfoSignUpActivity.java
) that load a picture (Bitmap) and create a UserPersona
Object that I want to pass into another Activity (UserGeneralDataSignUpActivity
).
我对解决方案进行了研究,尽管它已经implements Parcelable
,但是我仍然无法通过位图图像.
I did a research for solutions and somehow I am still unable to pass the Bitmap image although it is already implements Parcelable
.
有什么建议吗? 这是我的代码(没有getters和setters)
Any suggestions? Here is my code (without getters & setters)
PersonaUser.java:
public class PersonaUser implements Parcelable{
private String puName;
private String puEmailAddress;
private String puCountry;
private String puCity;
private int puAge;
private Bitmap puImage;
public PersonaUser(String puName, String puEmailAddress, String puCountry, String puCity,
int puAge, Bitmap puImage){
this.puName = puName;
this.puEmailAddress = puEmailAddress;
this.puCountry = puCountry;
this.puCity = puCity;
this.puAge = puAge;
this.puImage = puImage;
}
//Constructor using parcel
public PersonaUser(Parcel in) {
this.puName = in.readString();
this.puEmailAddress = in.readString();
this.puCountry = in.readString();
this.puCity = in.readString();
this.puAge = in.readInt();
this.puImage = (Bitmap) in.readValue(Bitmap.class.getClassLoader());
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(puName);
parcel.writeString(puEmailAddress);
parcel.writeString(puCountry);
parcel.writeString(puCity);
parcel.writeInt(puAge);
parcel.writeValue(puImage);
}
public static final Parcelable.Creator<PersonaUser> CREATOR = new Parcelable.Creator<PersonaUser>() {
@Override
public PersonaUser createFromParcel(Parcel in) {
return new PersonaUser(in); //using parcelable constructor
}
@Override
public PersonaUser[] newArray(int i) {
return new PersonaUser[i];
}
};
}
UserPrivateInfoSignUpActivity.java:
public class UserPrivateInfoSignUpActivity extends AppCompatActivity {
private static int IMAGES_FROM_GALLERY = 1;
Button nextActivityButton, pickImageButton;
Bitmap puImageBitmap;
PersonaUser npUser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_private_info_sign_up);
nextActivityButton = findViewById(R.id.next_activity);
pickImageButton = findViewById(R.id.pick_image);
addImage();
nextActivity();
}
//Get image from gallery
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
puImageBitmap = null;
//Detects request codes
if (requestCode == IMAGES_FROM_GALLERY && resultCode == Activity.RESULT_OK) {
Uri selectedImage = data.getData();
try {
puImageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ImageView imageView = (ImageView) findViewById(R.id.imgView);
imageView.setImageBitmap(puImageBitmap);
}
// next Activity
public void nextActivity(){
nextActivityButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(UserPrivateInfoSignUpActivity.this,
UserGeneralDataSignUpActivity.class);
npUser = new PersonaUser("example", "example","example","example",21,puImageBitmap);
i.putExtra("user" , npUser);
startActivity(i);
}
});
}
//add Image method
public void addImage(){
pickImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(i, IMAGES_FROM_GALLERY);
}
});
}
}
UserGeneralDataSignUpActivity.java (我要在其中检索用户对象的地方)
UserGeneralDataSignUpActivity.java (where I want to retrieve the user object)
public class UserGeneralDataSignUpActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_general_data_sign_up);
Intent i = getIntent();
ImageView iv = findViewById(R.id.show); //where I want to display image
PersonaUser pu = i.getParcelableExtra("user");
iv.setImageBitmap(pu.getPuImage()); //PersonaUser method (returns Bitmap)
}
它成功移至下一个活动,尽管每次我加载图片然后此后尝试移至下一个活动时,我的应用都会崩溃.
It successfully move to the next Activty, though each time I load a picture and afterwards try moving to the next Activity my app crashes.
04-15 10:40:09.720 20654-20654/com.rarely1gmail.personas E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 3687084)
04-15 10:40:09.721 20654-20654/com.rarely1gmail.personas D/AndroidRuntime: Shutting down VM
04-15 10:40:09.725 20654-20654/com.rarely1gmail.personas E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.rarely1gmail.personas, PID: 20654
java.lang.RuntimeException: Failure from system
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1618)
at android.app.Activity.startActivityForResult(Activity.java:4487)
at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:67)
at android.app.Activity.startActivityForResult(Activity.java:4445)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:720)
at android.app.Activity.startActivity(Activity.java:4806)
at android.app.Activity.startActivity(Activity.java:4774)
at com.rarely1gmail.personas.UserPrivateInfoSignUpActivity$1.onClick(UserPrivateInfoSignUpActivity.java:74)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: android.os.TransactionTooLargeException: data parcel size 3687084 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:764)
at android.app.IActivityManager$Stub$Proxy.startActivity(IActivityManager.java:4351)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1611)
at android.app.Activity.startActivityForResult(Activity.java:4487)
at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:67)
at android.app.Activity.startActivityForResult(Activity.java:4445)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:720)
at android.app.Activity.startActivity(Activity.java:4806)
at android.app.Activity.startActivity(Activity.java:4774)
at com.rarely1gmail.personas.UserPrivateInfoSignUpActivity$1.onClick(UserPrivateInfoSignUpActivity.java:74)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
谢谢.
推荐答案
在两个活动之间传递位图不是一个好主意.尝试这样做会得到TransactionTooLargeException
.交易数据的最大限制为1MB左右,位图可能会轻易地使其超调.这可能会导致崩溃.
Its not a great idea to pass Bitmap between two activities. You would get TransactionTooLargeException
when you attempt to do so. Maximum limit for transaction data is around 1MB and Bitmap could easily overshoot it. This could lead to crash.
您可以通过以下代码使用在onActivityResult()
中获得的URI:
You can just use the URI that you are getting in onActivityResult()
via following code:
Uri selectedImage = data.getData();
在活动之间传递此URI.然后,您可以按需使用URI加载图像,而不是传输整个Bitmap对象.
Pass this URI between the activities. You can then load image using the URI on-demand rather than transfering whole Bitmap object.
@SabaJafarzade谢谢指出,重用Uri.
@SabaJafarzade Thank you pointing out, to reuse the Uri.
这篇关于如何将包含位图的对象传递给另一个活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!