当前位置: 代码迷 >> java >> 如何快速将位图从活动传递到另一个?
  详细解决方案

如何快速将位图从活动传递到另一个?

热度:82   发布时间:2023-08-04 09:18:20.0

我试图将一个活动的位图传递给另一个,我尝试了多种解决方案,但它们的速度不够快。

当前,我面临这个问题:单击下一步按钮时,它冻结2秒钟,然后移动到下一个活动,并在ImageView中显示正确的位图。

我在StackoverFlow中找到了这个解决方案。 这是代码:

  Uri imageUri = intent.getParcelableExtra("URI");
        if (imageUri != null) {
            imageView.setImageURI(imageUri);
            try {
                bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(this, "No image is set to show", Toast.LENGTH_LONG).show();
        }

  btn_next_process.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (bitmap == null) {
                Toast.makeText(CropResultActivity.this, "Emptyyy", Toast.LENGTH_SHORT).show();
            }
            else {
                try {
                    //Write file
                    String filename = "bitmap.png";
                    FileOutputStream stream = CropResultActivity.this.openFileOutput(filename, Context.MODE_PRIVATE);
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);

                    //Cleanup
                    stream.close();
                  //  bitmap.recycle();

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

然后,我尝试首先将文件保存在辅助线程中,然后单击下一步按钮以进行检索,现在它的运行速度很快,但是我得到了错误的位图。

这是代码:

  Uri imageUri = intent.getParcelableExtra("URI");
        if (imageUri != null) {
            imageView.setImageURI(imageUri);
            try {
                bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);

                new Thread() {
                    @Override
                    public void run() {
                        try {
                            //Write file
                            FileOutputStream stream = CropResultActivity.this.openFileOutput(filename, Context.MODE_PRIVATE);
                            bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
                            //Cleanup
                            stream.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }.run();

            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(this, "No image is set to show", Toast.LENGTH_LONG).show();
        }

  btn_next_process.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (bitmap == null) {
                Toast.makeText(CropResultActivity.this, "Empty", Toast.LENGTH_SHORT).show();
            }
            else {
                //Pop intent
                Intent in1 = new Intent(CropResultActivity.this, InputProcessingActivity.class);
                in1.putExtra("image_data", filename);
                startActivity(in1);
            }
        }
    });

在第二个活动中,我以这种方式检索位图:

  private void getIncomingIntent(){
    if(getIntent().hasExtra("image_data")){
        try {
            String filename = getIntent().getStringExtra("image_data");
            FileInputStream is = this.openFileInput(filename);
            imageToProcess = BitmapFactory.decodeStream(is);
            process_detect_edges(imageToProcess);
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

我究竟做错了什么?

只需将图像uri传递到下一个活动即可。 从uri在其他活动中加载。

  1. 创建一个琐碎的Service 给该Service一个public Bitmap mBitmap成员。
  2. 当每个ActivityonStart()onStop()之间时,请使其与Service绑定。
  3. 如果您的Activities引用了Service ,那么它们可以直接通过mBitmap成员进行通信。 一个Activity可以设置mBitmap ,然后启动另一个Activity 第二个Activity可以简单地获取引用(当然是在绑定之后),然后开始操作Bitmap 由于一切都发生在UI线程上,因此没有同步问题。 一切都很快。

此解决方案不能解决持久性问题:如果用户离开应用程序一段时间(将其置于背景,锁定屏幕等),则整个应用程序可能会被破坏,而mBitmap将会丢失。 但是,如果您只是想在两个连续的Activities之间共享数据,这是一种简单的方法。

您甚至可以通过public static引用(位于任何方便的类中)共享Bitmap 有传言说,垃圾收集器会一时兴起将static引用设置为null ,但这是对实际行为的错误解释:整个应用程序可能会在意外的时间清理。 当您返回到Activity ,系统实际上可能必须重新启动应用程序并从头开始创建Activity 在这种情况下,引用将重置为null

取而代之的是,使用Service会向OS表示您的应用程序组件应具有更长的使用寿命。 当然,它会继续存在于两个连续Activities之间的间隙中。

请注意,在Oreo及更高版本上,系统在清除应用程序时会非常积极地清理它们。

  相关解决方案