问题描述
我试图将一个活动的位图传递给另一个,我尝试了多种解决方案,但它们的速度不够快。
当前,我面临这个问题:单击下一步按钮时,它冻结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();
}
}
}
我究竟做错了什么?
1楼
只需将图像uri传递到下一个活动即可。 从uri在其他活动中加载。
2楼
-
创建一个琐碎的
Service
。 给该Service
一个public Bitmap mBitmap
成员。 -
当每个
Activity
在onStart()
和onStop()
之间时,请使其与Service
绑定。 -
如果您的
Activities
引用了Service
,那么它们可以直接通过mBitmap
成员进行通信。 一个Activity
可以设置mBitmap
,然后启动另一个Activity
。 第二个Activity
可以简单地获取引用(当然是在绑定之后),然后开始操作Bitmap
。 由于一切都发生在UI线程上,因此没有同步问题。 一切都很快。
此解决方案不能解决持久性问题:如果用户离开应用程序一段时间(将其置于背景,锁定屏幕等),则整个应用程序可能会被破坏,而mBitmap
将会丢失。
但是,如果您只是想在两个连续的Activities
之间共享数据,这是一种简单的方法。
您甚至可以通过public static
引用(位于任何方便的类中)共享Bitmap
。
有传言说,垃圾收集器会一时兴起将static
引用设置为null
,但这是对实际行为的错误解释:整个应用程序可能会在意外的时间清理。
当您返回到Activity
,系统实际上可能必须重新启动应用程序并从头开始创建Activity
。
在这种情况下,引用将重置为null
。
取而代之的是,使用Service
会向OS表示您的应用程序组件应具有更长的使用寿命。
当然,它会继续存在于两个连续Activities
之间的间隙中。
请注意,在Oreo及更高版本上,系统在清除应用程序时会非常积极地清理它们。