React Native Android使用PDF生成库报Bitmap空指针错误求助
Let's break down why you're hitting this error and walk through how to fix it step by step:
Root Causes of the Error
This null pointer exception happens because the PDF generation library can't load your images properly—either the paths you're passing are invalid, the image data isn't accessible, or you're using a URI format the library can't handle (super common on Android). Here's what's off in your current code:
Incorrect handling of multiple selected images
Whenmultiple: trueis set inImagePicker.openPicker, the callback returns an array of image objects, not a single image. Your current code tries to pushimage.pathdirectly, which would either pushundefined(sinceimageis an array here) or only process one image incorrectly.Non-persistent state for image paths
Declaringvar photoPath = [];inside your component function means this array gets reset every time your component re-renders. By the time you try to generate the PDF, the array might not hold the paths you expect.Android URI compatibility issue
On Android,react-native-image-crop-pickerreturns acontent://URI instead of a direct file system path. Libraries likereact-native-image-to-pdfcan't resolve these URIs to bitmaps natively, leading to the null Bitmap error you're seeing.
Step-by-Step Fix
Here's the revised code with all issues addressed:
import * as React from 'react'; import {View, Button, Dimensions, Platform} from 'react-native'; import ImagePicker from 'react-native-image-crop-picker'; import RNImageToPdf from 'react-native-image-to-pdf'; import RNFS from 'react-native-fs'; // Install via npm install react-native-fs const {width: deviceWidth, height: deviceHeight} = Dimensions.get('window'); const App = () => { // Use useState to persist image paths across component re-renders const [photoPaths, setPhotoPaths] = React.useState([]); const handlePick = async () => { try { // Get the full array of selected images const images = await ImagePicker.openPicker({ multiple: true, }); // Convert Android content URIs to valid file paths const processedPaths = await Promise.all( images.map(async (image) => { if (Platform.OS === 'android' && image.path.startsWith('content://')) { // Resolve content URI to a readable file path const realPath = await RNFS.copyFileAssets(image.path, RNFS.DocumentDirectoryPath + `/temp_${Date.now()}.jpg`); return RNFS.DocumentDirectoryPath + `/temp_${Date.now()}.jpg`; } return image.path; }) ); // Update state with valid paths setPhotoPaths(processedPaths); // Generate the PDF const options = { imagePaths: processedPaths, name: 'PDFName', maxSize: { width: 900, height: Math.round((deviceHeight / deviceWidth) * 900), }, quality: 0.7, }; const pdf = await RNImageToPdf.createPDFbyImages(options); console.log('PDF generated at:', pdf.filePath); } catch (e) { console.error('Error during PDF generation:', e); } }; return ( <View style={{padding: 20}}> <Button title="Pick images" onPress={handlePick} /> </View> ); }; export default App;
Key Fixes Explained
- Use
useStatefor image paths: This ensures your selected image paths are retained even when the component re-renders, avoiding unexpected empty arrays. - Handle multiple images correctly: We iterate over the full
imagesarray returned by the picker, processing every selected image. - Resolve Android content URIs: We use
react-native-fsto copy the content URI-backed image to a local file path that the PDF library can read directly. - Simplify async flow: Replaced nested promise chains with
async/awaitfor cleaner, more maintainable code and better error handling.
Additional Checks
- Make sure you've added the required permissions to your
AndroidManifest.xml:<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - For Android API 30+, you may need to adjust scoped storage settings or request the
MANAGE_EXTERNAL_STORAGEpermission if your use case requires it.
内容的提问来源于stack exchange,提问作者g-mahendra

