Android Studio:不启动RecyclerView所属Activity时如何传递数据?
针对你需要提前给RecyclerView所在的Scanned_List_Activity传递数据,但不想立刻启动它的需求,提供以下几种实用方案:
方案一:全局单例临时存储
这是最简单直接的方式,用一个单例类临时保存数据,等用户主动打开目标Activity时再读取。
创建一个单例类:
public class DataHolder { private static DataHolder instance; private Bitmap scannedImage; private String imageClass; private DataHolder() {} public static DataHolder getInstance() { if (instance == null) { instance = new DataHolder(); } return instance; } // 设置数据 public void setScannedData(Bitmap image, String className) { this.scannedImage = image; this.imageClass = className; } // 获取图片(可选:取完清空避免重复使用) public Bitmap getScannedImage() { Bitmap temp = scannedImage; scannedImage = null; return temp; } // 获取分类(可选:取完清空避免重复使用) public String getImageClass() { String temp = imageClass; imageClass = null; return temp; } }
在当前Activity中保存数据:
public void sendData(Bitmap images, String image_class) { DataHolder.getInstance().setScannedData(images, image_class); // 这里无需启动Activity,等用户点击按钮时再触发启动逻辑 }
在Scanned_List_Activity的onCreate中读取数据:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scanned_list); Bitmap image = DataHolder.getInstance().getScannedImage(); String imageClass = DataHolder.getInstance().getImageClass(); // 用这两个数据更新RecyclerView }
优点:实现简单,无需序列化/转码,适合临时存储;缺点:如果用户杀进程,数据会丢失,不适合持久化场景。
方案二:修复SharedPreferences的Base64问题
你之前遇到的Base64.DEFAULT问题,大概率是因为它会自动添加换行符导致解析失败,换成Base64.NO_WRAP即可解决,同时正确处理Bitmap的转存逻辑:
在当前Activity中保存数据:
public void sendData(Bitmap images, String image_class) { SharedPreferences sp = getSharedPreferences("ScannedData", MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); // 保存分类字符串 editor.putString("image_class", image_class); // Bitmap转字节数组再转Base64字符串 ByteArrayOutputStream baos = new ByteArrayOutputStream(); images.compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] bytes = baos.toByteArray(); String imageBase64 = Base64.encodeToString(bytes, Base64.NO_WRAP); editor.putString("image_base64", imageBase64); editor.apply(); }
在Scanned_List_Activity中读取数据:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scanned_list); SharedPreferences sp = getSharedPreferences("ScannedData", MODE_PRIVATE); String imageClass = sp.getString("image_class", ""); String imageBase64 = sp.getString("image_base64", ""); // 解析Base64为Bitmap Bitmap image = null; if (!imageBase64.isEmpty()) { byte[] bytes = Base64.decode(imageBase64, Base64.NO_WRAP); image = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } // 更新RecyclerView }
优点:数据持久化,杀进程后不会丢失;缺点:Bitmap转Base64会增加内存占用,不适合大量图片存储场景。
方案三:用Jetpack ViewModel共享数据
如果你的项目使用Jetpack组件,ViewModel是更规范的组件间数据共享方式,它会自动处理生命周期,避免内存泄漏:
首先创建共享ViewModel:
import androidx.lifecycle.ViewModel; public class ScannedDataViewModel extends ViewModel { private Bitmap scannedImage; private String imageClass; public void setData(Bitmap image, String className) { this.scannedImage = image; this.imageClass = className; } public Bitmap getScannedImage() { return scannedImage; } public String getImageClass() { return imageClass; } }
在当前Activity中设置数据:
public void sendData(Bitmap images, String image_class) { ScannedDataViewModel viewModel = new ViewModelProvider(this).get(ScannedDataViewModel.class); viewModel.setData(images, image_class); }
在Scanned_List_Activity中读取数据:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scanned_list); ScannedDataViewModel viewModel = new ViewModelProvider(this).get(ScannedDataViewModel.class); Bitmap image = viewModel.getScannedImage(); String imageClass = viewModel.getImageClass(); // 更新RecyclerView }
优点:生命周期安全,无需手动管理数据销毁,适合现代Android项目;缺点:需要依赖Jetpack组件。
另外要说明:你之前用Intent + startActivity()的方式,本质是用来启动Activity并传递启动参数的,所以必然会打开目标页面,不符合你的预存数据需求,因此不能用这种方式。
内容的提问来源于stack exchange,提问作者Codifer

