我在尝试使用 ReactNativeFile 和 apollo-upload-client 上传文件时遇到与 okhttp3.internal.Util 相关的 ClassNotFoundException。此外,当使用 Blob 实例时,后端会收到一个空文件参数,尽管在使用 Postman 测试时文件上传工作正常。
const handleDocumentSelection = async () => {
try {
const res = await DocumentPicker.pick({
type: [
DocumentPicker.types.pdf,
DocumentPicker.types.doc,
DocumentPicker.types.docx,
DocumentPicker.types.images,
],
copyTo:
Platform.OS === 'android' ? 'cachesDirectory' : 'documentDirectory',
});
const uploadFile = async (fileUri, fileName, mimeType) => {
const file = new ReactNativeFile({
uri: fileUri,
name: 'picture.jpg',
type: mimeType
});
console.log('File object to be uploaded:', file);
try {
const { data } = await uploadImageMutation({
variables: { file },
});
console.log('Upload response:', data);
} catch (error) {
console.error('Upload error:', error);
}
};
const { fileCopyUri, name, type } = res[0];
uploadFile(fileCopyUri, name, type);
} catch (err) {
if (DocumentPicker.isCancel(err)) {
// Handle cancel
} else {
throw err;
}
}
};
### 使用 Blob 实例:
const handleDocumentSelection = async () => {
try {
const res = await DocumentPicker.pick({
type: [
DocumentPicker.types.pdf,
DocumentPicker.types.doc,
DocumentPicker.types.docx,
DocumentPicker.types.images,
],
copyTo:
Platform.OS === 'android' ? 'cachesDirectory' : 'documentDirectory',
});
const convertUriToBlob = async (uri, mimeType) => {
const base64Data = await RNFetchBlob.fs.readFile(uri, 'base64');
const byteCharacters = atob(base64Data);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
return new Blob([byteArray], { type: mimeType });
};
const uploadFile = async (fileUri, fileName, mimeType) => {
const fileBlob = await convertUriToBlob(fileUri, mimeType);
// Create a file object with a Blob instance
const file = new File([fileBlob], fileName, { type: mimeType });
console.log('File object to be uploaded:', file);
try {
const { data } = await uploadImageMutation({
variables: { file },
});
console.log('Upload response:', data);
} catch (error) {
console.error('Upload error:', error);
}
};
const { fileCopyUri, name, type } = res[0];
uploadFile(fileCopyUri, name, type);
} catch (err) {
if (DocumentPicker.isCancel(err)) {
// Handle cancel
} else {
throw err;
}
}
};
### 崩溃日志
原因:java.lang.ClassNotFoundException:未找到类 路径上的“okhttp3.internal.Util”:DexPathList[[zip 文件 “/data/app/~~6kd2JTp1gbPoLfrIrCABCA==/care.heyme.mobile-MkqSROqHXIAMbKVAbAvP-w==/base.apk”],nativeLibraryDirectories=[/data/app/~~6kd2JTp1gbPoLfrIrCABCA==/care.heyme.mobile- MkqSROqHXIAMbKVAbAvP-w==/lib/arm64, /data/app/~~6kd2JTp1gbPoLfrIrCABCA==/care.heyme.mobile-MkqSROqHXIAMbKVAbAvP-w==/base.apk!/lib/arm64-v8a、/system/lib64、/product_h/lib64、/system_ext/lib64]]
macOS:14.1.1 节点:16.0.0 npm:7.10.0 反应本机:0.68.1 阿波罗上传客户端:11.0.0 Android SDK:API 级别 30、31、33、34、35 Android 工作室:2024.1 Java:17.0.11
### 附加信息
尽管使用了最新版本的 apollo-upload-client,问题仍然存在。 使用 Blob 实例时,后端收到空文件参数,但在 Postman 中上传正常。
任何人都可以协助解决这个问题吗?是否存在可以解决此 ClassNotFoundException 和 Blob 实例问题的已知兼容性问题或配置设置?
@apollo/client
版本3.8.7
解决方案:
1/需要在 app/build.gradle 中实现 Okhttp :
implementation 'com.squareup.okhttp3:okhttp:3.8.0'
implementation 'com.squareup.okhttp3:okhttp-urlconnection:3.8.0'
2/ 还强制使用此版本:3.8.0 在 android/build.gradle 中,如下所示:
allprojects {
configurations.all {
resolutionStrategy {
force 'com.squareup.okhttp3:okhttp:3.8.0'
force 'com.squareup.okhttp3:okhttp-urlconnection:3.8.0'
}
}
}