程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 討論:如何在NDK中呼叫Java的class

討論:如何在NDK中呼叫Java的class

編輯:關於JAVA

討論:如何在NDK中呼叫Java的class。本站提示廣大學習愛好者:(討論:如何在NDK中呼叫Java的class)文章只能為提供參考,不一定能成為您想要的結果。以下是討論:如何在NDK中呼叫Java的class正文


廢話不多說,直接上碼.......

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讓文字往上對齊

// 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

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;
}


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 類對象。第二個參數是參數(或辦法名),第三個參數是該參數(或辦法)的簽名。
那要如何獲得辦法的簽名呢?
我們要應用Javap -s TextManager這個指令來做

首先到.class所在的文件夾下,在我的范例中是在D:\CloudAndroid\CloudBox\CloudBoxAndroidGameApplication\bin\com\clouddevelop\cloudbox
然後鍵入javap -s TextManager就可以失掉了,Signature就是我們要的簽名。



辛勞了這麼久,我的CloudBox終於能顯示文字了!!!!!!
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved