Android: l'appel d'une classe Java à partir de C++ Natif de l'Activité
De code 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 source:
...
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);
...
il échoue avec:
W/dalvikvm(5614): dvmFindClassByName en rejetant 'Llocal/ttt/Text2Bitmap;' W/dalvikvm(5614): threadid=9: thread sortir avec uncaught exception (groupe=0x4002d560) E/AndroidRuntime(5614): FATAL EXCEPTION: Thread-10 E/AndroidRuntime(5614): java.lang.ClassNotFoundException: Llocal/ttt/Text2Bitmap; dans le chargeur de dalvik.système.PathClassLoader[.] E/AndroidRuntime(5614): à dalvik.système.PathClassLoader.findClass(PathClassLoader.java:240) E/AndroidRuntime(5614): à java.lang.Chargeur de classe.loadClass(ClassLoader.java:551) E/AndroidRuntime(5614): à java.lang.Chargeur de classe.loadClass(ClassLoader.java:511) E/AndroidRuntime(5614): à dalvik.système.NativeStart.exécuter(Native method)
Tout soupçon de ce que je fais de mal, s'il vous plaît?
- Avez-vous essayé de débogage? Code dumps ne sont pas vraiment casher ici
- Cette question est un cauchemar, mais j'ai pris un coup de couteau à elle de toute façon. Vous devez pour identifier la ligne de code natif est à l'origine de l'erreur (puisque nous n'avons pas les numéros de ligne).
- je ne peux pas utiliser le débogage dans mon anvironment. Je test sur l'appareil je ne peux pas racine. afin de débogage ne fonctionne pas ici. la question est à propos de la partie c, pas de java.
- il causer d'erreur sur "échoue ici" dans le code c.
- Voir ma réponse ensuite, essayez certaines de mes suggestions.
- Mon mauvais. il a travaillé sans modification, sauf que j'ai mis android:hasCode à true dans le manifeste. lol
Vous devez vous connecter pour publier un commentaire.
Ne plaisante pas avec java de la classe loader. Utilisez ce code:
Pas sûr de ce qui est la cause de votre erreur (vous n'indiquent pas où les lignes sont, ou la ligne où vous avez de la difficulté de débogage), mais je vais aller de l'avant et de souligner quelques erreurs que je vois.
Une première erreur est que vous devez utiliser
CallStaticObjectMethod
depuis que vous êtes à l'appel d'une méthode statique. Votrejmethodid findClass
a un methodID, pas une classe, qui est erronée et trompeuse. Vous avez également deux paramètres, mais vous semblez être seulement en passant un paramètre.Fondamentalement, vous avez besoin de:
(env)->GetStaticMethodID(jclass,"method name", "Parameter list")
--jclass est la classe de référence
--"la méthode nom" est le nom de la méthode DANS les citations
--"Liste des paramètres" est la liste des paramètres, vous devez rechercher la syntaxe.
Sauter un peu les choses...Pour appeler vos trucs dont vous avez besoin:
(env)->CallStaticObjectMethod(jclass,jmid,parameter1,parameter2)
--jclass est une fois de plus la classe qui a la méthode statique.
--jmid est la méthode java id qui vous obtenez à partir de la fonction ci-dessus.
--paramètre1 et paramètre2 sont les paramètres requis pour la méthode java.
Enfin, je pense que ce n'est peut-être la préférence, mais je ne voudrais pas attacher le fil à la JVM jusqu'à ce que vous ayez toutes les informations nécessaires pour faire le saut dans la JVM.