源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

探讨:如何在NDK中呼叫Java的class

  • 时间:2022-12-03 08:59 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:探讨:如何在NDK中呼叫Java的class
废话不多说,直接上码.......
[u]复制代码[/u] 代码如下:
package com.clouddevelop.cloudbox; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.FontMetrics; public class TextManager {     public Bitmap create(String text, float size)     {         try         {             Paint paint = new Paint();             paint.setColor(Color.WHITE);             paint.setTextSize(size);             paint.setAlpha(255);             paint.setFlags(Paint.ANTI_ALIAS_FLAG);             paint.setTextAlign(Paint.Align.LEFT);             paint.setAntiAlias(true);             float[] widths = new float[text.length()];;             paint.getTextWidths(text, widths);             float width = 0;             for(int i = 0 ;i < widths.length ; i++)                 width += widths[i];             FontMetrics fm = paint.getFontMetrics();             int mFontHeight = (int) (Math.ceil(fm.descent - fm.top) + 2);             Bitmap textImg = Bitmap.createBitmap((int)width, mFontHeight, Bitmap.Config.ARGB_8888);             Canvas c = new Canvas(textImg);             if(fm.ascent < 0)                 c.drawText(text,0,(float)Math.abs(fm.ascent),paint);             else                 c.drawText(text,0,fm.ascent* -1,paint);             return textImg;         }         catch (Exception e) { }         return null;     }     public int getWidth(Bitmap bmp) { return bmp.getWidth(); }     public int getHeight(Bitmap bmp) { return bmp.getHeight(); }     public void getPixels(Bitmap bmp, int[] pixels)     {         int w = bmp.getWidth();         int h = bmp.getHeight();         bmp.getPixels(pixels, 0, w, 0, 0, w, h);     }     public void close(Bitmap bmp)     {         bmp.recycle();     } }
要在NDK中呼叫Java的类,第一步当然要有一个Java的类,这个类是我自行建立 要产生一个文字的Bitmap,技术上没什么复杂性,建立Paint,建立Bitmap然后用Canvas将文字写入 在Canvas的drawText中,会使用FontMetrics的值来写入文字,所以利用fm.ascent让文字往上对齐
[u]复制代码[/u] 代码如下:
// declare JNIEXPORT void JNICALL Java_com_clouddevelop_cloudbox_CloudRenderer_nativeTextInit (JNIEnv* env, jclass cls, jobject textManager); // implement JNIEXPORT void JNICALL Java_com_clouddevelop_cloudbox_CloudRenderer_nativeTextInit (JNIEnv* env, jclass cls, jobject textManager) {     g_env = env;     g_textmgr = textManager;     jclass business_class = env->GetObjectClass(g_textmgr);     AndroidLog("initial textmanager success!"); }
接下来要在JNI中将JNIEnv存到全域变量中g_env
[u]复制代码[/u] 代码如下:
jobject getInstance(JNIEnv* env, jclass obj_class) {     jmethodID construction_id = env->GetMethodID(obj_class, "<init>", "()V");     jobject obj = env->NewObject(obj_class, construction_id);     return obj; } GLuint createText(const char* text, float size,float* rWidth, float* rHeight) {     if(g_env)         AndroidLog("g_env exist");     if(g_textmgr)         AndroidLog("g_textmgr exist");     jclass order_class = g_env->FindClass("com/clouddevelop/cloudbox/TextManager");     AndroidLog("FindClass succeed");     g_textmgr = getInstance(g_env, order_class);     jclass cls = g_env->GetObjectClass(g_textmgr);     AndroidLog("get class succeed");     jmethodID mid;     mid = g_env->GetMethodID(cls, "create",                              "(Ljava/lang/String;F)Landroid/graphics/Bitmap;");     AndroidLog("get create succeed");     jstring data = g_env->NewStringUTF(text);     jobject textImage = g_env->CallObjectMethod(g_textmgr, mid, data,size);     AndroidLog("call create succeed");     g_env->DeleteLocalRef(data);     g_env->NewGlobalRef(textImage);     /* Get image dimensions */     mid = g_env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I");     int width = g_env->CallIntMethod(g_textmgr, mid, textImage);     AndroidLog("call getWidth succeed");     mid = g_env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I");     int height = g_env->CallIntMethod(g_textmgr, mid, textImage);     AndroidLog("call getHeight succeed");     *rWidth = width;     *rHeight = height;     /* Get pixels */     jintArray image_data = g_env->NewIntArray(width * height);     g_env->NewGlobalRef(image_data);     mid = g_env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V");     g_env->CallVoidMethod(g_textmgr, mid, textImage, image_data);     AndroidLog("call getPixels succeed");     jint *pixels = g_env->GetIntArrayElements(image_data, 0);     //Now generate the OpenGL texture object     GLuint texture;     glGenTextures(1, &texture);     glBindTexture(GL_TEXTURE_2D, texture);     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,           GL_UNSIGNED_BYTE, (GLvoid*) pixels);     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);     AndroidLog("generate texture succeed");     g_env->ReleaseIntArrayElements(image_data, pixels, 0);     g_env->DeleteGlobalRef(image_data);     /* Free image */     mid = g_env->GetMethodID(cls, "close", "(Landroid/graphics/Bitmap;)V");     g_env->CallVoidMethod(g_textmgr, mid, textImage);     AndroidLog("call close succeed");     g_env->DeleteGlobalRef(textImage);     return texture; }
[u]复制代码[/u] 代码如下:
jobject getInstance(JNIEnv* env, jclass obj_class) {     jmethodID construction_id = env->GetMethodID(obj_class, "<init>", "()V");     jobject obj = env->NewObject(obj_class, construction_id);     return obj; }
上面这段代码,是在native code中创建一个Java的实体类 这段代码是我的CloudBox中创建文字纹理的代码 mid = g_env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I"); int width = g_env->CallIntMethod(g_textmgr, mid, textImage); 其中这两行,GetMethodID先取得该类的方法 在GetMethodID中第一参数是Java 类对象。第二个参数是参数(或方法名),第三个参数是该参数(或方法)的签名。 [b]那要如何取得方法的签名呢? [/b]我们要利用Javap -s TextManager这个指令来做 [img]http://files.jb51.net/file_images/article/201305/201305311012218.gif[/img] 首先到.class所在的文件夹下,在我的范例中是在D:\CloudAndroid\CloudBox\CloudBoxAndroidGameApplication\bin\com\clouddevelop\cloudbox 然后键入javap -s TextManager就可以得到了,Signature就是我们要的签名。 [img]http://files.jb51.net/file_images/article/201305/201305311012219.gif[/img] 辛苦了这么久,我的CloudBox终于能显示文字了!!!!!!
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部