Creating a Java VM from Android Native Code

本文介绍了如何在Android原生代码中创建Java虚拟机实例的方法,包括标准方法、UiccUnlock方法及Surfaceflinger方法,并提供了最终实现代码。

If you’re writing native / JNI code for Android, it’s probably as native method of an Android app. These methods are always passed the Dalvik VM instance of the app as the first parameter. You need this to create jstrings and other Java objects, lookup classes and fields, etc. It’s not normal for you to have to instantiate a VM from native code because most of the time, if you’re using the Java Native Interface (JNI), you started in Java land and are only dipping into native code land for them sweet, sweet performance benefits. However, if you’re reverse engineering or writing an exploit, you’re likely always delving int all kinds of unusual trouble which the developers reasonably believed would never happen or at least would only be a theoretical edge case.

I recently needed to create a VM from native code to pass Java object arguments to a JNI function. In this post, I want to share what I came up with and why I finally settled on this particular method.

Standard Method

The official, standard method is documented here: How to Create a JVM Instance in JNI. Unfortunately, this won’t work in Android because jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*) isn’t exported. Even if you’re not familiar with this function, it’s name should be a clue that it’s important. If you want to check if it’s not exported yourself, look at jni.h from your Android NDK directory. In my case, it’s in android-sdk/android-ndk-r13b/platforms/android-9/arch-x86/usr/include/jni.h. The relevant code is:

     
1
2
3
4
5
     
#if 0 /* In practice, these are not exported by the NDK so don't declare them */
jint JNI_GetDefaultJavaVMInitArgs(void*);
jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);
#endif

If you try to compile the code, you’ll probably get an error like this:

     
1
2
     
warning: implicit declaration of function 'JNI_CreateJavaVM' is invalid in C99
[-Wimplicit-function-declaration]

The official documentation is still useful for understanding the API and what all those options and arguments do. But if we want to use this on Android, we’re going to have to explicitly load the necessary methods from some library.

One useful detail this code shows is how to set the VM’s class path. Here’s how it’s done:

     
1
2
     
JavaVMOption jvmopt[ 1];
jvmopt[ 0].optionString = "-Djava.class.path=" + ".";

This sets the class path to the current directory (.). This is needed if you want your VM to access system or app classes. Some early experiments show that setting to a directory doesn’t seem to work. I tried setting to /data/local/tmp and pushing naked DEX files, as well as a JAR containing DEX files and the app’s APK. The only option that worked was setting the full path to either the JARDEX, or the APK. What was odd is that system classes (i.e. java.lang.String) were not accessible without having at least one valid file in the class path. In other words, (*env)->FindClass(env, "java.lang.String") returns 0 unless there’s at least one file on the class path, even though java.lant.String is defined in the framework.

To test yourself, push an APK to the emulator or device:

     
1
     
adb push shim_app.apk /data/ local/tmp

Use this for your JavaVMOption:

     
1
2
3
4
5
     
JavaVMOption opt[ 2];
opt[ 0].optionString = "-Djava.class.path=/data/local/tmp/shim_app.apk";
opt[ 1].optionString = "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
// ...
args.nOptions = 2;

You should now be able to use FindClass to load system and app classes.

And if you need to load native libraries in your VM, such as if you load a class which loads a library in it’s static initilzer, you can see that path as well with optionString = "-Djava.library.path=/data/local/tmp". There’s an example here.

UiccUnlock Method

My genius cyber-sleuth skills revealed another possible technique. It’s from UiccUnlock.cpp which looks like a quasi-exploit to do a SIM unlock.

I won’t claim to fully understand what it’s doing, but the interesting part to me is in get_transation_code. Here’s what it does:

  • creates a Java VM
  • use the VM to get reference to com.android.internal.telephony.ITelephony$Stub class
  • get the TRANSACTION_sendOemRilRequestRaw field value
  • destroy the VM
  • return field value

It looks like the field value is used to check if the device is already unlocked or perhaps to check if the unlock method will work. I’m not sure. I just wanted to rip out the code to create the VM.

The approach seemed sound: load the relevant VM creation functions by through libnativehelper.so or libdvm.so as a backup. However, there were a few lines in there that looked weird:

     
1
2
3
     
JniInvocation_ctor = (JniInvocation_ctor_t) dlsym(libnativehelper, "_ZN13JniInvocationC1Ev");
JniInvocation_dtor = (JniInvocation_dtor_t) dlsym(libnativehelper, "_ZN13JniInvocationD1Ev");
JniInvocation_Init = (JniInvocation_Init_t) dlsym(libnativehelper, "_ZN13JniInvocation4InitEPKc");

I couldn’t find these functions documented anywhere. Someone really clever figured these out (kudos!). Without calling these functions, you get some weird errors:

     
1
2
3
4
     
W/dalvikvm(5395): No implementation found for native Landroid/os/SystemProperties;.native_get:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
W/dalvikvm(5395): No implementation found for native Landroid/os/SystemProperties;.native_get:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
W/dalvikvm(5395): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Landroid/os/Build;
A/libc(5395): Fatal signal 11 (SIGSEGV) at 0x0000000c (code=1), thread 5395 (create_vm)

Despite these weird functions, this approach totally worked for me. But I wanted to understand what the _ZN13JniInvocationC1Evfunctions did and if they were portable between Android versions. My gut told me that hardcoding that many function names which also included numbers could lead to incompatibilities in some devices or in later Android versions.

Surfaceflinger Method

I eventually found code from Google’s Surfaceflinger service: DdmConnection.cpp.

This defaults to looking for JNI_CreateJavaVM in libdvm.so. Instead of calling _ZN13JniInvocation* methods, it looks like it calls Java_com_android_internal_util_WithFramework_registerNatives from libandroid_runtime.so. The behavior of registerNatives is described well here.

Also interesting are the options used to create the VM:

     
1
     
opt.optionString = "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";

These options are well documented here and according to the documentation, this just allows for debugging of the JVM. Seems pretty standard.

I noticed the JNI version was 1_4, but I bumped it up to 1_6 because that’s what’s used in the example code here. Here are the supported versions from jni.h:

     
1
2
3
4
     
#define JNI_VERSION_1_1 0x00010001
#define JNI_VERSION_1_2 0x00010002
#define JNI_VERSION_1_4 0x00010004
#define JNI_VERSION_1_6 0x00010006

I ended up using this approach since I figured it’s the most robust and future-proof because it comes from Google.

Final Code

Here’s the final code to create the VM:

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
     
#include <dlfcn.h>
#include <jni.h>
typedef int (*JNI_CreateJavaVM_t)(void *, void *, void *);
typedef jint (*registerNatives_t)(JNIEnv* env, jclass clazz);
static int init_jvm(JavaVM **p_vm, JNIEnv **p_env) {
// https://android.googlesource.com/platform/frameworks/native/+/ce3a0a5/services/surfaceflinger/DdmConnection.cpp
JavaVMOption opt[ 4];
opt[ 0].optionString = "-Djava.class.path=/data/local/tmp/shim_app.apk";
opt[ 1].optionString = "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
opt[ 2].optionString = "-Djava.library.path=/data/local/tmp";
opt[ 3].optionString = "-verbose:jni"; // may want to remove this, it's noisy
JavaVMInitArgs args;
args.version = JNI_VERSION_1_6;
args.options = opt;
args.nOptions = 4;
args.ignoreUnrecognized = JNI_FALSE;
void *libdvm_dso = dlopen( "libdvm.so", RTLD_NOW);
void *libandroid_runtime_dso = dlopen( "libandroid_runtime.so", RTLD_NOW);
if (!libdvm_dso || !libandroid_runtime_dso) {
return -1;
}
JNI_CreateJavaVM_t JNI_CreateJavaVM;
JNI_CreateJavaVM = (JNI_CreateJavaVM_t) dlsym(libdvm_dso, "JNI_CreateJavaVM");
if (!JNI_CreateJavaVM) {
return -2;
}
registerNatives_t registerNatives;
registerNatives = (registerNatives_t) dlsym(libandroid_runtime_dso, "Java_com_android_internal_util_WithFramework_registerNatives");
if (!registerNatives) {
return -3;
}
if (JNI_CreateJavaVM(&(*p_vm), &(*p_env), &args)) {
return -4;
}
if (registerNatives(*p_env, 0)) {
return -5;
}
return 0;
}

Here’s how it’s used:

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
     
#include <stdlib.h>
#include <stdio.h>
JavaVM * vm = NULL;
JNIEnv * env = NULL;
int status = init_jvm( & vm, & env);
if (status == 0) {
printf( "Initialization success (vm=%p, env=%p)\n", vm, env);
} else {
printf( "Initialization failure (%i)\n", status);
return -1;
}
jstring testy = (*env)->NewStringUTF(env, "this should work now!");
const char *str = (*env)->GetStringUTFChars(env, testy, NULL);
printf( "testy: %s\n", str);

Conclusion

Now you have everything you need to instantiate a Java VM from native code. You should also have a decent understanding (or at least links to documentation) about some of the options available to you. To see a practical application of this technique, check out Calling JNI Functions with Java Object Arguments from the Command Line.

原文地址: http://calebfenton.github.io/2017/04/05/creating_java_vm_from_android_native_code/

2025-10-30 19:03:55.611 16318-16318 MainActivity com.tencent.yolov5ncnn D decodeVideo: ------------/-1/2/content:/media/external/video/media/29/ORIGINAL/NONE/video/mp4/1895746813===============/-1/2/content://media/external/video/media/29/ORIGINAL/NONE/video/mp4/1895746813 2025-10-30 19:03:55.678 16318-16325 cent.yolov5ncnn com.tencent.yolov5ncnn I NativeAlloc concurrent mark compact GC freed 1145KB AllocSpace bytes, 3(60KB) LOS objects, 49% free, 1919KB/3839KB, paused 8.932ms,4.182ms total 57.817ms 2025-10-30 19:03:55.717 1938-1951 DatabaseUtils com...ndroid.providers.media.module E Writing exception to parcel java.lang.SecurityException: com.tencent.yolov5ncnn has no access to content://media/external/video/media/29 at com.android.providers.media.MediaProvider.enforceCallingPermissionInternal(MediaProvider.java:11734) at com.android.providers.media.MediaProvider.enforceCallingPermission(MediaProvider.java:11631) at com.android.providers.media.MediaProvider.checkAccess(MediaProvider.java:11755) at com.android.providers.media.MediaProvider.checkAccessForThumbnail(MediaProvider.java:9929) at com.android.providers.media.MediaProvider.ensureThumbnail(MediaProvider.java:9848) at com.android.providers.media.MediaProvider.openTypedAssetFileCommon(MediaProvider.java:9833) at com.android.providers.media.MediaProvider.openTypedAssetFile(MediaProvider.java:9773) at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:677) at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:341) at android.os.Binder.execTransactInternal(Binder.java:1421) at android.os.Binder.execTransact(Binder.java:1365) 2025-10-30 19:03:55.722 16318-16318 MediaStore com.tencent.yolov5ncnn W Failed to obtain thumbnail for content://media/external/video/media/29 java.io.IOException: java.lang.SecurityException: com.tencent.yolov5ncnn has no access to content://media/external/video/media/29 at android.graphics.ImageDecoder$CallableSource.createImageDecoder(ImageDecoder.java:615) at android.graphics.ImageDecoder.decodeBitmapImpl(ImageDecoder.java:1858) at android.graphics.ImageDecoder.decodeBitmap(ImageDecoder.java:1850) at android.content.ContentResolver.loadThumbnail(ContentResolver.java:4173) at android.content.ContentResolver.loadThumbnail(ContentResolver.java:4157) at android.provider.MediaStore$InternalThumbnails.getThumbnail(MediaStore.java:2932) at android.provider.MediaStore$Video$Thumbnails.getThumbnail(MediaStore.java:4612) at com.tencent.yolov5ncnn.MainActivity.decodeVideo(MainActivity.java:450) at com.tencent.yolov5ncnn.MainActivity.onActivityResult(MainActivity.java:237) at android.app.Activity.onActivityResult(Activity.java:7626) at android.app.Activity.internalDispatchActivityResult(Activity.java:9546) at android.app.Activity.dispatchActivityResult(Activity.java:9523) at android.app.ActivityThread.deliverResults(ActivityThread.java:6173) at android.app.ActivityThread.handleSendResult(ActivityThread.java:6223) at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:78) at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:63) at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem(TransactionExecutor.java:133) at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:103) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:80) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2823) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loopOnce(Looper.java:248) at android.os.Looper.loop(Looper.java:338) at android.app.ActivityThread.main(ActivityThread.java:9067) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932) Caused by: java.lang.SecurityException: com.tencent.yolov5ncnn has no access to content://media/external/video/media/29 at android.os.Parcel.createExceptionOrNull(Parcel.java:3340) at android.os.Parcel.createException(Parcel.java:3324) at android.os.Parcel.readException(Parcel.java:3307) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:201) at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:164) at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:814) at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:2045) at android.content.ContentResolver.openTypedAssetFile(ContentResolver.java:1950) at android.content.ContentResolver.lambda$loadThumbnail$0(ContentResolver.java:4174) at android.content.ContentResolver$$ExternalSyntheticLambda0.call(D8$$SyntheticClass:0) at android.graphics.ImageDecoder$CallableSource.createImageDecoder(ImageDecoder.java:610) ... 26 more 2025-10-30 19:03:55.771 16318-16318 ThumbnailUtils com.tencent.yolov5ncnn W java.io.IOException: Failed to create thumbnail at android.media.ThumbnailUtils.createVideoThumbnail(ThumbnailUtils.java:391) at android.media.ThumbnailUtils.createVideoThumbnail(ThumbnailUtils.java:333) at com.tencent.yolov5ncnn.MainActivity.decodeVideo(MainActivity.java:454) at com.tencent.yolov5ncnn.MainActivity.onActivityResult(MainActivity.java:237) at android.app.Activity.onActivityResult(Activity.java:7626) at android.app.Activity.internalDispatchActivityResult(Activity.java:9546) at android.app.Activity.dispatchActivityResult(Activity.java:9523) at android.app.ActivityThread.deliverResults(ActivityThread.java:6173) at android.app.ActivityThread.handleSendResult(ActivityThread.java:6223) at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:78) at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:63) at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem(TransactionExecutor.java:133) at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:103) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:80) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2823) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loopOnce(Looper.java:248) at android.os.Looper.loop(Looper.java:338) at android.app.ActivityThread.main(ActivityThread.java:9067) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932) Caused by: java.lang.IllegalArgumentException: /storage/emulated/0/Download/20251011_112303.mp4 does not exist at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:255) at android.media.ThumbnailUtils.createVideoThumbnail(ThumbnailUtils.java:362) ... 21 more 2025-10-30 19:03:55.776 16318-16318 MainActivity com.tencent.yolov5ncnn D decodeVideo_address: ====================/storage/emulated/0/Download/20251011_112303.mp4-------/storage/emulated/0 2025-10-30 19:03:55.956 16318-16318 MediaCodecList com.tencent.yolov5ncnn D codecHandlesFormat: no format, so no extra checks 2025-10-30 19:03:55.958 16318-16318 MediaCodecList com.tencent.yolov5ncnn D codecHandlesFormat: no format, so no extra checks 2025-10-30 19:03:55.969 16318-16389 CCodec com.tencent.yolov5ncnn D allocate(c2.goldfish.h264.decoder) 2025-10-30 19:03:55.975 16318-16389 ApexCodecsLazy com.tencent.yolov5ncnn I Failed to load libcom.android.media.swcodec.apexcodecs.so: dlopen failed: library "libcom.android.media.swcodec.apexcodecs.so" not found 2025-10-30 19:03:55.975 16318-16389 Codec2Client com.tencent.yolov5ncnn I Available Codec2 services: "default" "software" 2025-10-30 19:03:55.985 16318-16389 CCodec com.tencent.yolov5ncnn I setting up 'default' as default (vendor) store 2025-10-30 19:03:56.003 16318-16389 CCodec com.tencent.yolov5ncnn I Created component [c2.goldfish.h264.decoder] for [c2.goldfish.h264.decoder] 2025-10-30 19:03:56.005 16318-16389 CCodecConfig com.tencent.yolov5ncnn D read media type: video/avc 2025-10-30 19:03:56.023 16318-16389 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: algo.buffers.max-count.values 2025-10-30 19:03:56.024 16318-16389 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: output.subscribed-indices.values 2025-10-30 19:03:56.025 16318-16389 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: input.buffers.allocator-ids.values 2025-10-30 19:03:56.026 16318-16389 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: output.buffers.allocator-ids.values 2025-10-30 19:03:56.027 16318-16389 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: algo.buffers.allocator-ids.values 2025-10-30 19:03:56.027 16318-16389 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: output.buffers.pool-ids.values 2025-10-30 19:03:56.028 16318-16389 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: algo.buffers.pool-ids.values 2025-10-30 19:03:56.033 16318-16389 ReflectedParamUpdater com.tencent.yolov5ncnn D ignored struct field coded.color-format.locations 2025-10-30 19:03:56.041 16318-16389 ReflectedParamUpdater com.tencent.yolov5ncnn D ignored struct field resources.needed.values 2025-10-30 19:03:56.041 16318-16389 CCodecConfig com.tencent.yolov5ncnn D ignoring local param raw.size (0xd2001800) as it is already supported 2025-10-30 19:03:56.041 16318-16389 CCodecConfig com.tencent.yolov5ncnn D ignoring local param default.color (0x5200180b) as it is already supported 2025-10-30 19:03:56.041 16318-16389 ReflectedParamUpdater com.tencent.yolov5ncnn D ignored struct field raw.hdr-static-info.mastering 2025-10-30 19:03:56.044 16318-16389 CCodecConfig com.tencent.yolov5ncnn I query failed after returning 12 values (BAD_INDEX) 2025-10-30 19:03:56.045 16318-16389 CCodecConfig com.tencent.yolov5ncnn D c2 config diff is Dict { c2::u32 coded.pl.level = 20496 c2::u32 coded.pl.profile = 20481 c2::u32 coded.vui.color.matrix = 0 c2::u32 coded.vui.color.primaries = 0 c2::u32 coded.vui.color.range = 2 c2::u32 coded.vui.color.transfer = 0 c2::u32 default.color.matrix = 0 c2::u32 default.color.primaries = 0 c2::u32 default.color.range = 0 c2::u32 default.color.transfer = 0 c2::u32 input.buffers.max-size.value = 6291456 c2::u32 input.delay.value = 0 string input.media-type.value = "video/avc" c2::u32 output.delay.value = 8 string output.media-type.value = "video/raw" c2::u32 raw.color.matrix = 0 c2::u32 raw.color.primaries = 0 c2::u32 raw.color.range = 2 c2::u32 raw.color.transfer = 0 c2::u32 raw.max-size.height = 240 c2::u32 raw.max-size.width = 320 c2::u32 raw.pixel-format.value = 35 c2::i32 raw.rotation.flip = 0 c2::i32 raw.rotation.value = 0 c2::u32 raw.sar.height = 1 c2::u32 raw.sar.width = 1 c2::u32 raw.size.height = 240 c2::u32 raw.size.width = 320 c2: 2025-10-30 19:03:56.046 16318-16389 ColorUtils com.tencent.yolov5ncnn W expected specified color aspects (2:0:0:0) 2025-10-30 19:03:56.080 16318-16318 TransactionExecutor com.tencent.yolov5ncnn E Failed to execute the transaction: tId:551909865 ClientTransaction{ tId:551909865 transactionItems=[ tId:551909865 TopResumedActivityChangeItem{mActivityToken=android.os.BinderProxy@7bd4eec,onTop=true} tId:551909865 Target activity: com.tencent.yolov5ncnn.MainActivity tId:551909865 ActivityResultItem{mActivityToken=android.os.BinderProxy@7bd4eec,resultInfoList=[ResultInfo{who=null, request=2, result=-1, data=Intent { dat=content://com.google.android.apps.photos.contentprovider/... flg=0x1 xflg=0x4 clip={text/uri-list {U(content)}} }}]} tId:551909865 Target activity: com.tencent.yolov5ncnn.MainActivity tId:551909865 ResumeActivityItem{mActivityToken=android.os.BinderProxy@7bd4eec,procState=2,isForward=false,shouldSendCompatFakeFocus=false} tId:551909865 Target activity: com.tencent.yolov5ncnn.MainActivity tId:551909865 ] tId:551909865 } 2025-10-30 19:03:56.081 16318-16318 AndroidRuntime com.tencent.yolov5ncnn D Shutting down VM 2025-10-30 19:03:56.082 16318-16318 AndroidRuntime com.tencent.yolov5ncnn E FATAL EXCEPTION: main Process: com.tencent.yolov5ncnn, PID: 16318 java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { dat=content://com.google.android.apps.photos.contentprovider/... flg=0x1 xflg=0x4 clip={text/uri-list {U(content)}} }} to activity {com.tencent.yolov5ncnn/com.tencent.yolov5ncnn.MainActivity}: java.lang.IllegalArgumentException: The surface has been released at android.app.ActivityThread.deliverResults(ActivityThread.java:6184) at android.app.ActivityThread.handleSendResult(ActivityThread.java:6223) at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:78) at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:63) at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem(TransactionExecutor.java:133) at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:103) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:80) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2823) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loopOnce(Looper.java:248) at android.os.Looper.loop(Looper.java:338) at android.app.ActivityThread.main(ActivityThread.java:9067) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932) Caused by: java.lang.IllegalArgumentException: The surface has been released at android.media.MediaCodec.native_configure(Native Method) at android.media.MediaCodec.configure(MediaCodec.java:2562) at android.media.MediaCodec.configure(MediaCodec.java:2422) at com.tencent.yolov5ncnn.MainActivity.decodeVideo(MainActivity.java:514) at com.tencent.yolov5ncnn.MainActivity.onActivityResult(MainActivity.java:237) at android.app.Activity.onActivityResult(Activity.java:7626) at android.app.Activity.internalDispatchActivityResult(Activity.java:9546) at android.app.Activity.dispatchActivityResult(Activity.java:9523) at android.app.ActivityThread.deliverResults(ActivityThread.java:6173) ... 14 more
最新发布
10-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值