Android:从C ++ Native Activity调用Java类

Java代码:

package local.ttt; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Typeface; public class Text2Bitmap { static Bitmap getBitmap(String text,int fontsize) { Paint paint=new Paint(); paint.setStyle(Paint.Style.FILL); paint.setColor(Color.WHITE); paint.setTextSize(fontsize); paint.setAntiAlias(true); paint.setTypeface(Typeface.DEFAULT); int outwidth=(int)Math.round(paint.measureText(text)); Bitmap bitmap=Bitmap.createBitmap(outwidth,fontsize,Bitmap.Config.ALPHA_8); Canvas canvas=new Canvas(bitmap); canvas.drawText(text,0,fontsize-1,paint); return bitmap; } } 

C源:

 ... MY_ASSERT(vm_cached!=NULL); JNIEnv* env; jint res=vm_cached->AttachCurrentThread(&env,NULL); MY_ASSERT(res==0); jclass activityClass=env->FindClass("android/app/NativeActivity"); MY_ASSERT(activityClass!=NULL); jmethodID getClassLoader=env->GetMethodID(activityClass,"getClassLoader","()Ljava/lang/ClassLoader;"); MY_ASSERT(getClassLoader!=NULL); MY_ASSERT(nativeActivityObjHnd!=NULL); jobject cls=env->CallObjectMethod(nativeActivityObjHnd,getClassLoader); jclass classLoader=env->FindClass("java/lang/ClassLoader"); MY_ASSERT(classLoader!=NULL); jmethodID findClass=env->GetMethodID(classLoader,"loadClass","(Ljava/lang/String;)Ljava/lang/Class;"); MY_ASSERT(findClass!=NULL); jstring strClassName=env->NewStringUTF("Llocal/ttt/Text2Bitmap;"); jclass text2bitmapClass=(jclass)env->CallObjectMethod(cls,findClass,strClassName); //fails here MY_ASSERT(text2bitmapClass!=NULL); res=vm_cached->DetachCurrentThread(); MY_ASSERT(res==0); ... 

它失败了:

 W / dalvikvm(5614):dvmFindClassByName拒绝'Llocal / ttt / Text2Bitmap;'
 W / dalvikvm(5614):threadid = 9:线程退出未捕获的exception(组= 0x4002d560)
 E / AndroidRuntime(5614):致命exception:线程-10
 E / AndroidRuntime(5614):java.lang.ClassNotFoundException:Llocal / ttt / Text2Bitmap; 在loader dalvik.system.PathClassLoader [。]中
 E / AndroidRuntime(5614):at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:240)
 E / AndroidRuntime(5614):在java.lang.ClassLoader.loadClass(ClassLoader.java:551)
 E / AndroidRuntime(5614):在java.lang.ClassLoader.loadClass(ClassLoader.java:511)
 E / AndroidRuntime(5614):at dalvik.system.NativeStart.run(Native Method)

有什么暗示我做错了吗?

不要乱用java类加载器。 使用此代码:

 MY_ASSERT(vm_cached!=NULL); JNIEnv* env; jint res = vm_cached->AttachCurrentThread(&env,NULL); MY_ASSERT(res==0); jclass t2bClass = env->FindClass("local/ttt/Text2Bitmap"); MY_ASSERT(t2bClass!=NULL); jmethodID getBitmap = env->GetStaticMethodID(t2bClass, "getBitmap","(Ljava/lang/String;I)Landroid/graphics/Bitmap;"); MY_ASSERT(getBitmap!=NULL); jstring text = ...; int fontsize = ...; jobject bitmap = env->CallStaticObjectMethod(t2bClass, getBitmap, text, fontsize); MY_ASSERT(bitmap!=NULL); // process bitmap here // ... res=vm_cached->DetachCurrentThread(); MY_ASSERT(res==0); 

不确定是什么导致了你的错误(你没有指出行的位置,或者你调试有困难的特定行),但我会继续指出我看到的一些快速错误。

第一个错误是您需要使用CallStaticObjectMethod因为您正在调用静态方法。 你的jmethodid findClass有一个methodID,而不是一个类,这是误导和错误的。 您还有两个参数,但您似乎只传递一个参数。

基本上,你需要:

(env)->GetStaticMethodID(jclass,"method name", "Parameter list")

–jclass是类引用 – “方法名称”是IN引号的方法名称 – “参数列表”是参数列表,您需要查找语法。

跳过一些事情……要打电话给你需要的东西:

(env)->CallStaticObjectMethod(jclass,jmid,parameter1,parameter2)

–jclass再一次是具有静态方法的类。 –jmid是你从上面的函数得到的java方法id。 –parameter1和parameter2是java方法所需的参数。

最后,我认为这可能只是偏好,但我不会将该线程附加到JVM,直到您获得跳转到JVM的所有必要信息。