Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android利用JNI調用C++自定義類

android利用JNI調用C++自定義類

編輯:關於Android編程

找了好久關於android調用C/C++庫的文章,但是始終沒有一片是關於android利用jni調用C++自定義類的文章,無奈只好看android的源代碼,學習android的圖形庫的實現,因為它的實現底層也是利用C++的skia庫。下面就3個文件來描述。


首先是你在java中的一個類,用於你在應用程序中調用這裡取名叫Person類

[java] 
package whf.jnitest; 
 
public class Person { 
     
    static 
    { 
        System.loadLibrary("Person"); 
    } 
     
    private int mNativePerson; 
     
    public Person() 
    { 
        mNativePerson = init(); 
    } 
    protected void finalize() 
    { 
        try { 
            finalizer(mNativePerson); 
        } finally { 
            try { 
                super.finalize(); 
            } catch (Throwable e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } 
        } 
    }    
    public int getAge() 
    { 
        return native_getAge(mNativePerson); 
    } 
     
    public void setAge(int age) 
    { 
        native_setAge(mNativePerson, age); 
    } 
 
    private native void finalizer(int nPerson); 
    public  native int  add(int a, int b); 
    public  native int  sub(int a, int b); 
    private native int  init(); 
     
    private native int  native_getAge(int nPerson); 
    private native void native_setAge(int nPerson, int age); 

然後你的C++文件就如下,我定義為CPerson類
[cpp] 
#define LOG_TAG "this is a first JNI test" 
 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <assert.h> 
#include "jni.h" 
#include "CPerson.h" 
 
 
 
    jint add(JNIEnv *env, jobject obj, jint a, jint b) 
    { 
        return a + b; 
    } 
 
    jint Java_whf_jnitest_Person_sub(JNIEnv *env, jobject obj, jint a, jint b) 
    { 
        return a - b; 
    } 
 
    void Java_whf_jnitest_Person_finalizer(JNIEnv *env, jobject clazz, CPerson *obj) 
    { 
        delete obj; 
    } 
 
    CPerson * Java_whf_jnitest_Person_init(JNIEnv *env, jobject clazz) 
    { 
        CPerson *p = new CPerson(); 
        return p; 
    } 
 
    void Java_whf_jnitest_Person_setAge(JNIEnv *env, jobject clazz, CPerson *obj, jint age) 
    { 
        return obj->setAge(age); 
    } 
 
    jint Java_whf_jnitest_Person_getAge(JNIEnv *env, jobject clazz, CPerson *obj) 
    { 
        return obj->getAge(); 
    } 
 
    static JNINativeMethod methods[]{ 
        {"add", "(II)I", (void *)add}, 
        {"sub", "(II)I", (void *)Java_whf_jnitest_Person_sub}, 
        {"finalizer", "(I)V", (void *)Java_whf_jnitest_Person_finalizer}, 
        {"init", "()I", (void *)Java_whf_jnitest_Person_init}, 
        {"native_setAge", "(II)V", (void *)Java_whf_jnitest_Person_setAge}, 
        {"native_getAge", "(I)I", (void *)Java_whf_jnitest_Person_getAge}, 
    }; 
 
    static const char * classPathName = "whf/jnitest/Person"; 
 
    static int registerNativeMethods(JNIEnv* env, const char* className, 
        JNINativeMethod* gMethods, int numMethods) 
    { 
        jclass clazz; 
 
        clazz = env->FindClass(className); 
        if (clazz == NULL) { 
            //LOGE("Native registration unable to find class '%s'", className); 
            return JNI_FALSE; 
        } 
        if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) { 
            //LOGE("RegisterNatives failed for '%s'", className); 
            return JNI_FALSE; 
        } 
 
        return JNI_TRUE; 
    } 
 
    static int registerNatives(JNIEnv* env) 
    { 
      if (!registerNativeMethods(env, classPathName, 
                     methods, sizeof(methods) / sizeof(methods[0]))) { 
        return JNI_FALSE; 
      } 
 
      return JNI_TRUE; 
    } 
 
    typedef union { 
        JNIEnv* env; 
        void* venv; 
    } UnionJNIEnvToVoid; 
 
    /* This function will be call when the library first be loaded */ 
    jint JNI_OnLoad(JavaVM* vm, void* reserved) 
    { 
        UnionJNIEnvToVoid uenv; 
        JNIEnv* env = NULL; 
        //LOGI("JNI_OnLoad!"); 
 
        if (vm->GetEnv((void**)&uenv.venv, JNI_VERSION_1_4) != JNI_OK) { 
            //LOGE("ERROR: GetEnv failed"); 
            return -1; 
        } 
 
        env = uenv.env;; 
 
        //jniRegisterNativeMethods(env, "whf/jnitest/Person", methods, sizeof(methods) / sizeof(methods[0])); 
 
        if (registerNatives(env) != JNI_TRUE) { 
            //LOGE("ERROR: registerNatives failed"); 
            return -1; 
        } 
 
         return JNI_VERSION_1_4; 
    } 

CPerson的聲明如下:
[cpp] 
#ifndef _CPERSON_H_ 
#define _CPERSON_H_ 
 
class CPerson 

private: 
    int m_age; 
public: 
    CPerson(); 
    int getAge(); 
    void setAge(int age); 
}; 
 
#endif  www.2cto.com

這樣一個簡單的JNI調用C++自定義類就實現了


作者:wanghaofeng
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved