繁体   English   中英

如何在Android中为动态选择的图像创建savedInstanceState?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM