zoukankan      html  css  js  c++  java
  • android JNI学习之一

    执行System.loadLibrary()函数时,VM会反向调用*.so里的JNI_OnLoad()函数。用途有二:
    1. VM询问此*.so使用的JNI版本编号。
    2. VM要求*.so做一些初期设定工作(Initialization),例如登记<函数名称表>。

    •例如,在Android的jniload.so档案里,就提供了JNI_OnLoad()函数,其程序码片段为:

    /* com.misoo.counter.CounterNative.cpp */
    #include <stdio.h>
    #include<jni.h>
    #include <pthread.h>
    #include<android/log.h>
    #include "com_misoo_counter_CounterNative.h"
    //LOGE("ERROR: GetEnv failed
    ");
    #define LOGE(x)  __android_log_print(ANDROID_LOG_INFO,TAG,(x))
    jmethodID mid;
    jclass mClass;
    JavaVM *jvm;
    pthread_t thread;
    int n, sum;
    const char *TAG="JniTest";
    //int  ANDROID_LOG_INFO= 0;
    void* trRun(void*);
    void JNICALL Java_com_misoo_counter_CounterNative_nativeSetup(JNIEnv *env,
            jobject thiz) {
        jclass clazz = env->GetObjectClass(thiz);
        mClass = (jclass) env->NewGlobalRef(clazz);
        mid = env->GetStaticMethodID(mClass, "callback", "(I)V");
    }
    void JNICALL Java_com_misoo_counter_CounterNative_nativeExec(JNIEnv *env,
            jobject thiz, jint numb) {
        n = numb;
        pthread_create(&thread, NULL, trRun, NULL);
    }
    void* trRun(void*) {
        int status;
        JNIEnv *env;
        bool isAttached = false;
        status = jvm->GetEnv((void **) &env, JNI_VERSION_1_4);
        if (status < 0) {
            status = jvm->AttachCurrentThread(&env, NULL);
            if (status < 0)
                return NULL;
            isAttached = true;
        }
        sum = 0;
        for (int i = 0; i <= n; i++)
            sum += i;
        env->CallStaticVoidMethod(mClass, mid, sum);
        if (isAttached)
            jvm->DetachCurrentThread();
        return NULL;
    }
    
    static const char *classPathName = "com/misoo/counter/CounterNative";
    static JNINativeMethod methods[] = { { "init", "()V",
            (void *) Java_com_misoo_counter_CounterNative_nativeSetup }, {
            "execute", "(I)V",
            (void *) Java_com_misoo_counter_CounterNative_nativeExec } };
    static int registerNativeMethods(JNIEnv* env, const char* className,
            JNINativeMethod* gMethods, int numMethods) {
        __android_log_print(ANDROID_LOG_INFO,TAG,"registerNativeMethods");
        if(env == NULL)
            __android_log_print(ANDROID_LOG_INFO,TAG,"env is null");
        jclass clazz = env->FindClass(className);
        __android_log_print(ANDROID_LOG_INFO,TAG,"find class");
        __android_log_print(ANDROID_LOG_INFO,TAG,"%s",className);
        env->RegisterNatives(clazz, gMethods, numMethods);
        __android_log_print(ANDROID_LOG_INFO,TAG,"end registerNativeMethods");
        return JNI_TRUE;
    }
    static int registerNatives(JNIEnv* env) {
        __android_log_print(ANDROID_LOG_INFO,TAG,"registerNatives");
        registerNativeMethods(env, classPathName, methods,
                sizeof(methods) / sizeof(methods[0]));
        __android_log_print(ANDROID_LOG_INFO,TAG,"end registerNatives");
        return JNI_TRUE;
    }
    jint JNI_OnLoad(JavaVM* vm, void* reserved) {
        __android_log_print(ANDROID_LOG_INFO,TAG,"JNI_OnLoad");
        JNIEnv *env = NULL;
        jvm = vm;
         if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
                LOGE("ERROR: GetEnv failed
    ");
    //            return -1;
            }
    //    assert(env == NULL);
        if (registerNatives(env) != JNI_TRUE)
            return -1;
        __android_log_print(ANDROID_LOG_INFO,TAG,"JNI_OnLoad end");
        return JNI_VERSION_1_4;
    }



    Android.mk文件是:

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib -llog
    LOCAL_MODULE    :=jniload
    LOCAL_SRC_FILES :=archMultiThread.cpp
    
    include $(BUILD_SHARED_LIBRARY)

    Application.mk文件:

    APP_STL:=gnustl_static  
    APP_CPPFLAGS:=-frtti -fexceptions  
    APP_ABI:=armeabi armeabi-v7a
    APP_PLATFORM=android-8

    CounterNative.java

    package com.misoo.counter;
    
    import com.example.hellondk.MainActivity;
    
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    
    //CounterNative.java 
    // ……… 
    public class CounterNative {
        private static Handler h;
        public static final String TAG = "JniTest";
        static {
            Log.i(CounterNative.TAG, "try to load libMyJT002.so");
            System.loadLibrary("jniload");
            Log.i(CounterNative.TAG, "end try to load libMyJT002.so");
        }
    
        public CounterNative() {
            Log.i(CounterNative.TAG, "new CounterNative");
            init();
            Log.i(CounterNative.TAG, "init finished");
    
            h = new Handler() {
                public void handleMessage(Message msg) {
                    MainActivity.ref.setTitle("Hello …");
                }
            };
        }
    
        private static void callback(int a) {
            Message m = h.obtainMessage(1, a, 3, null);
            h.sendMessage(m);
        }
    
        private native void init();
    
        public native void execute(int numb);
    }
    package com.example.hellondk;
    
    import java.sql.Ref;
    
    import com.huml.ndk1.NativeJniAdder;
    import com.misoo.counter.CounterNative;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    
    public class MainActivity extends Activity {
        public static MainActivity ref = null;
        CounterNative obj;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ref= this;
            Log.i(CounterNative.TAG, "onCreate");
            obj = new CounterNative();
        }
    
    //对应一个Button的onClick事件,布局文件中一个Button按钮,布局文件很简单我就不列出来了
        public void TestNDK(View view){
            Log.i(NativeJniAdder.TAG, "start NDK");
            obj.execute(11);
        }
        
    }
  • 相关阅读:
    下载字体的正确姿势
    字体基础知识与实际运用
    CSP复习与模板
    地理必修三知识点
    LaTeX公式手册(全网最全)
    动态规划求解0/1背包问题
    JavaScript对象简介(一)
    DOM文档对象模型简介
    SQLServer 的case when语句使用实现统计
    批量初始化数组和memset函数
  • 原文地址:https://www.cnblogs.com/ronaldHU/p/5052754.html
Copyright © 2011-2022 走看看