You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CameraX拍摄并保存照片后跳转至另一个Fragment的实现方案

Solution: Navigate to Fragment2 on Main Thread After CameraX Photo Save

Hey Maria, this is a super common thread-related issue with CameraX—let’s break down how to fix it! The core problem here is that CameraX’s onImageSaved callback runs on your background cameraExecutor thread, and you can’t perform Fragment transactions (or any UI operations) off the main thread. Here’s the straightforward fix:

Core Fix: Switch to Main Thread for Navigation

You need to wrap your Fragment navigation code in a call that ensures it runs on the main thread. Android provides requireActivity().runOnUiThread { ... } for exactly this scenario—it posts your UI operation to the main thread’s message queue, even if you’re calling it from a background thread.

Modified Code Example

Let’s update your onImageSaved callback to include this main thread switch. Also, since you’re saving to Firestore, you’ll want to trigger navigation after that upload completes (to make sure the photo is fully saved before switching screens). Here’s the adjusted code:

override fun onImageSaved(output: ImageCapture.OutputFileResults) {
    val savedUri = output.savedUri ?: Uri.fromFile(photoFile)
    Log.d(TAG, "Photo capture succeeded: $savedUri")
    
    // Keep your media scanner code as-is
    val mimeType = MimeTypeMap.getSingleton()
        .getMimeTypeFromExtension(savedUri.toFile().extension)
    MediaScannerConnection.scanFile(
        context,
        arrayOf(savedUri.toFile().absolutePath),
        arrayOf(mimeType)
    ) { _, uri ->
        Log.d(TAG, "Image capture scanned into media store: $uri")
    }

    // Update saveToFireStoreStorage to use a completion callback
    saveToFireStoreStorage(photoFile, fileName) { uploadSuccess ->
        if (uploadSuccess) {
            photoFile.delete() // Clean up local file after successful upload
            
            // Navigate to Fragment2 on the MAIN thread
            requireActivity().runOnUiThread {
                // Replace with your actual navigation logic
                val navController = findNavController()
                navController.navigate(R.id.action_fragment1_to_fragment2)
                
                // If you're using FragmentManager instead of Navigation Component:
                // requireActivity().supportFragmentManager.beginTransaction()
                //     .replace(R.id.fragment_container, Fragment2())
                //     .addToBackStack(null)
                //     .commit()
            }
        } else {
            // Handle upload failure if needed
            Log.e(TAG, "Firestore upload failed")
        }
    }
}

Key Details to Note:

  • Why runOnUiThread? All UI operations (including Fragment transactions) are restricted to the main thread. CameraX uses your cameraExecutor (a background thread) for callbacks, so we explicitly switch back to main here to avoid crashes or freezes.
  • Wait for Firestore Upload: I added a lambda callback to saveToFireStoreStorage—you’ll need to update that function to invoke this callback once the Firestore upload finishes. This ensures you only navigate after the photo is safely stored in the cloud.
  • Alternative: Use view.post If you have a reference to your Fragment’s view (like binding.root), you could also use binding.root.post { ... } instead of runOnUiThread—it achieves the same result, as post sends the operation to the main thread.

If saveToFireStoreStorage is Synchronous:

If your Firestore save is synchronous (not recommended for network operations), you can simplify the code to:

saveToFireStoreStorage(photoFile, fileName)
photoFile.delete()

// Navigate on main thread
requireActivity().runOnUiThread {
    // Your navigation code here
}

This should resolve the thread issue and let you safely jump to Fragment2 right after the photo is processed and saved.

内容的提问来源于stack exchange,提问作者Maria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:49:10