在Android中使用Intent在Activity内传递Android位图数据

sgtfey8w  于 2022-12-25  发布在  Android
关注(0)|答案(8)|浏览(152)

我在活动1中有一个名为bmp的位图变量,我想将该位图发送到活动2
下面是我使用Intent传递它的代码。

Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image",bmp);
startActivity(in1);

在练习2中,我尝试使用以下代码访问位图

Bundle ex = getIntent().getExtras();
Bitmap bmp2 = ex.getParceable("image");
ImageView result = (ImageView)findViewById(R.Id.imageView1);
result.setImageBitmap(bmp);

应用程序正常运行,但未给予预期结果

avkwfej4

avkwfej41#

在将其添加到Intent、发送出去并解码之前,请将其转换为Byte数组。

//Convert to byte array
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();

Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image",byteArray);

然后在活动2中:

byte[] byteArray = getIntent().getByteArrayExtra("image");
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
    • 编辑**

我想我应该用最佳实践来更新这个:
在第一个练习中,您应该将位图保存到磁盘,然后在下一个练习中加载它。请确保在第一个练习中回收位图,以便为垃圾回收做好准备:
活动一:

try {
    //Write file
    String filename = "bitmap.png";
    FileOutputStream stream = this.openFileOutput(filename, Context.MODE_PRIVATE);
    bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
    
    //Cleanup
    stream.close();
    bmp.recycle();

    //Pop intent
    Intent in1 = new Intent(this, Activity2.class);
    in1.putExtra("image", filename);
    startActivity(in1);
} catch (Exception e) {
    e.printStackTrace();
}

在活动2中,加载位图:

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

cfh9epnr2#

有时,位图可能太大,无法进行编码和解码,或在Intent中作为字节数组传递。这可能会导致OOM或糟糕的UI体验。
我建议考虑将位图放入新Activity(使用它的Activity)的静态变量中,当您不再需要它时,该变量将谨慎地为null(这意味着在onDestroy中,但仅当“isChangingConfigurations”返回false时)。

qlzsbp2j

qlzsbp2j3#

简单地说,我们可以只传递位图的URI,而不是传递位图对象。如果位图对象很大,这将导致内存问题。
第一个活动。

intent.putExtra("uri", Uri);

从SecondActivity中,我们返回位图。

Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),Uri.parse(uri));
5kgi1eie

5kgi1eie4#

用于将位图发送到另一个Activity的Kotlin代码:
1-在第一个活动中:

val i = Intent(this@Act1, Act2::class.java)
           var bStream  =  ByteArrayOutputStream()
            bitmap.compress(Bitmap.CompressFormat.PNG, 50, bStream)
            val byteArray = bStream.toByteArray()
            i.putExtra("image", byteArray )
            startActivity(i)

2-在活动二(读取位图图像)中:

var bitmap : Bitmap? =null
    if (intent.hasExtra("image")){
      //convert to bitmap          
        val byteArray = intent.getByteArrayExtra("image")
        bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
    }

3-如果需要将其设置为视图的背景,如ConstraintLayout或...:

if (bitmap != null) {
     //Convert bitmap to BitmapDrawable
     var bitmapDrawable = BitmapDrawable( resources , bitmap)
      root_constraintLayout.backgroundDrawable = bitmapDrawable
   }
jmp7cifd

jmp7cifd5#

我们也可以在不通过Intent传递数据的情况下解决这个问题,只需将图像存储在内存中,并在下一个Activity中从该位置加载图像,这样也可以避免应用因传递大型位图数据而崩溃。您甚至不需要将位置路径传递给Intent,只需记住路径并使用它。

vq8itlhq

vq8itlhq6#

我还想为那些希望这样做的人发布一个最佳实践答案(但可能问错了问题)。
不要传递位图(我假设您是从网络下载的,否则,您已经有了一个文件引用),我建议使用像Universal Image Loader这样的图像加载器将图像下载到ImageView中,您可以配置它,然后将图像缓存到磁盘:

DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .considerExifParams(true)
                .bitmapConfig(Bitmap.Config.RGB_565)
                .build();
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
                .defaultDisplayImageOptions(defaultOptions)
                .build();

        ImageLoader.getInstance().init(config);

现在,只需在Intent中传递图像URL,然后使用UIL加载图像。例如,在新创建的Activity中,图像将立即加载,因为它是该高速缓存加载的,即使图像URL在下载后已过期。

goqiplq2

goqiplq27#

创建用于存储位图数据的单例类

public final class BitmapData {
    private static final BitmapData bitmapData = new BitmapData();
    private Bitmap bitmap;

    private BitmapData() {
    }

    public static BitmapData getInstance() {
        return bitmapData;
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }

在第一个练习中,您可以这样设置。

BitmapData.getInstance().setBitmap(bitmap);

在第二个活动中

Bitmap bitmap = BitmapData.getInstance().getBitmap();

注:检查空值

jdzmm42g

jdzmm42g8#

Bundle b = new Bundle();
b.putSerializable("Image", Bitmap);
mIntent.putExtras(b);
startActivity(mIntent);

相关问题