[英]how to create savedInstanceState for dynamically selected image in Android?
我創建了一個Android應用程序。使用按鈕從庫中選擇圖像並在ImageView中檢索。 圖像提取成功。 現在我想保存所選Image.It嘗試修復的狀態。它使崩潰應用程序。當我更改水平方向時,應用程序崩潰。請幫我解決問題。
我的代碼:
public class MainActivity extends ActionBarActivity {
ImageView imgBackground;
Button loadImgBtn;
String imgDecodableString;
Drawable drawable;
private static int RESULT_LOAD_IMG = 1;
private static final String IMAGE_DATA = "image_resource";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadImgBtn = (Button)findViewById(R.id.btnSelectImage);
imgBackground = (ImageView)findViewById(R.id.myImg);
loadImgBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/* Create intent to open Image Application like Gallery */
Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
/* start the Intent */
startActivityForResult(galleryIntent,RESULT_LOAD_IMG);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK && null != data) {
/* Get the Image from Data */
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
/* Get the Cursor */
Cursor cursor = getContentResolver().query(selectedImage,filePathColumn,null,null,null);
/* Move the first row */
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imgDecodableString = cursor.getString(columnIndex);
cursor.close();
/* Rendering the Image */
drawable = new BitmapDrawable(imgDecodableString);
imgBackground.setBackgroundDrawable(drawable);
}
} catch (Exception e) {
message(getBaseContext()," Error : " + e.getMessage(),Toast.LENGTH_SHORT);
}
}
public void message(Context ctx,String msg,int duration) {
Toast.makeText(ctx,msg,duration).show();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(IMAGE_DATA, (android.os.Parcelable) drawable);
}
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
drawable = (Drawable) savedInstanceState.getParcelable(IMAGE_DATA);
}
}
我沒有測試過這個,所以我不知道它是否正常工作。 希望是的。
但你應該意識到這一點
...您可能無法通過onSaveInstanceState()回調系統為您保存的Bundle完全恢復您的活動狀態 - 它不是為了攜帶大型對象(如位圖)及其中的數據而設計的必須序列化然后反序列化,這會占用大量內存並使配置變化緩慢。 在這種情況下,您可以通過在配置更改時重新啟動活動時保留有狀態對象來減輕重新初始化活動的負擔。
public class MainActivity extends ActionBarActivity {
ImageView imgBackground;
Button loadImgBtn;
String imgDecodableString;
BitmapDrawable drawable;
private static int RESULT_LOAD_IMG = 1;
private static final String IMAGE_DATA = "image_resource";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadImgBtn = (Button)findViewById(R.id.btnSelectImage);
imgBackground = (ImageView)findViewById(R.id.myImg);
loadImgBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/* Create intent to open Image Application like Gallery */
Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
/* start the Intent */
startActivityForResult(galleryIntent,RESULT_LOAD_IMG);
}
});
if(savedInstanceState != null) {
Bitmap tmp = savedInstanceState.getParcelable(IMAGE_DATA);
if(tmp != null) {
drawable = new BitmapDrawable(getResources(), tmp);
imgBackground.setImageDrawable(drawable);
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK && null != data) {
/* Get the Image from Data */
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
/* Get the Cursor */
Cursor cursor = getContentResolver().query(selectedImage,filePathColumn,null,null,null);
/* Move the first row */
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imgDecodableString = cursor.getString(columnIndex);
cursor.close();
/* Rendering the Image */
drawable = new BitmapDrawable(imgDecodableString);
imgBackground.setBackgroundDrawable(drawable);
}
} catch (Exception e) {
message(getBaseContext()," Error : " + e.getMessage(), Toast.LENGTH_SHORT);
}
}
public void message(Context ctx,String msg,int duration) {
Toast.makeText(ctx,msg,duration).show();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if(drawable != null && drawable.getBitmap() != null) {
outState.putParcelable(IMAGE_DATA, drawable.getBitmap());
}
}
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
}
}
使用帶有位圖的實例狀態時要小心。 正如Bojan所引用的那樣,你不應該使用通過'onSaveInstanceState'管理的Bundle來處理圖像。
這是更新的報價:
您可能無法使用系統為onSaveInstanceState()回調為您保存的Bundle完全恢復活動狀態 - 它不是為承載大型對象(如位圖)而設計的,並且其中的數據必須序列化然后反序列化,這會占用大量內存並使配置變化緩慢。 在這種情況下,您可以通過在配置更改時重新啟動活動時保留Fragment來減輕重新初始化活動的負擔。 此片段可以包含對要保留的有狀態對象的引用。
來自官方文件
您可以在此提示下找到我實現的代碼,在另一個問題上查看我的答案
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.