红米Note4中Fragment调用相机后Activity重建,如何显示图片?
解决红米Note4中Fragment调用相机后视图销毁、无法显示图片的问题
我来帮你搞定这个红米Note4上的相机调用坑!这个问题大概率是因为红米Note4的系统在启动相机时触发了配置变更(比如强制屏幕方向切换、系统内存回收触发Activity重建),导致你的Activity和Fragment被销毁重建,原本保存的图片状态跟着丢失了。下面给你几个针对性的解决方案:
1. 阻止Activity因配置变更自动重建
红米Note4的相机应用可能会偷偷修改屏幕配置,触发Activity重建。你可以在AndroidManifest.xml里给对应的Activity添加配置,让系统跳过重建流程:
<activity android:name=".YourMainActivity" android:configChanges="orientation|screenSize|keyboardHidden"> <!-- 其他配置 --> </activity>
添加这个配置后,系统不会重建Activity,而是调用onConfigurationChanged方法,你可以在这个方法里做简单的适配,不用重新加载Fragment和视图。
2. 手动保存Fragment的图片状态
即使Activity还是会重建,你也可以在Fragment里保存图片的临时路径,确保重建后能找回:
private String mImagePath; // 保存图片的绝对路径 @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); // 把图片路径存入Bundle if (mImagePath != null) { outState.putString("IMAGE_PATH", mImagePath); } } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // 重建时恢复图片路径并显示 if (savedInstanceState != null) { mImagePath = savedInstanceState.getString("IMAGE_PATH"); if (mImagePath != null) { displayCapturedImage(mImagePath); } } // 相机按钮点击事件 cameraBtn.setOnClickListener(v -> launchCamera()); }
3. 固定相机图片的存储路径,避免返回结果丢失
不要依赖onActivityResult里的Intent数据(重建后这些数据可能消失),提前创建一个临时文件来保存相机拍摄的图片,这样不管Activity怎么重建,都能通过路径找到图片:
private static final int REQUEST_IMAGE_CAPTURE = 1; private File createTempImageFile() throws IOException { // 创建唯一的临时文件名,避免重复 String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); String imageFileName = "CAMERA_" + timeStamp + "_"; File storageDir = requireContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES); return File.createTempFile(imageFileName, ".jpg", storageDir); } private void launchCamera() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(requireContext().getPackageManager()) != null) { File photoFile = null; try { photoFile = createTempImageFile(); mImagePath = photoFile.getAbsolutePath(); // 保存路径 } catch (IOException e) { e.printStackTrace(); Toast.makeText(requireContext(), "创建临时文件失败", Toast.LENGTH_SHORT).show(); return; } // 用FileProvider获取文件Uri(适配Android 7.0+) Uri photoUri = FileProvider.getUriForFile( requireContext(), "com.your.app.package.fileprovider", // 替换成你的FileProvider授权 photoFile ); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); } } @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) { // 直接用保存的路径加载图片 displayCapturedImage(mImagePath); } } private void displayCapturedImage(String imagePath) { // 这里可以用Glide/Picasso加载,比BitmapFactory更高效 // Glide.with(this).load(new File(imagePath)).into(yourImageView); Bitmap bitmap = BitmapFactory.decodeFile(imagePath); yourImageView.setImageBitmap(bitmap); }
4. 确保Activity重建时找回原来的Fragment
有些红米机型会在内存紧张时回收Activity,重建时如果重新创建Fragment实例,之前的状态就没了。你可以在Activity的onCreate里检查是否有已存在的Fragment:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState == null) { // 第一次启动时添加Fragment getSupportFragmentManager().beginTransaction() .add(R.id.fragment_container, YourCameraFragment.class, "CAMERA_FRAGMENT_TAG") .commit(); } else { // 重建时找回原来的Fragment实例 YourCameraFragment fragment = (YourCameraFragment) getSupportFragmentManager() .findFragmentByTag("CAMERA_FRAGMENT_TAG"); // 可以在这里做一些状态恢复操作 } }
按照上面的步骤调整代码,应该就能解决红米Note4上的这个问题了——核心就是避免Activity/Fragment重建时丢失图片的关键信息,或者直接阻止不必要的重建。
内容的提问来源于stack exchange,提问作者Lakshmi Priya Vikram
相关产品推荐
相关产品推荐

