android JNI學習之一

來源:互聯網
上載者:User

標籤:

執行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\n");#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\n");//            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 -llogLOCAL_MODULE    :=jniloadLOCAL_SRC_FILES :=archMultiThread.cppinclude $(BUILD_SHARED_LIBRARY)

Application.mk檔案:

APP_STL:=gnustl_static  APP_CPPFLAGS:=-frtti -fexceptions  APP_ABI:=armeabi armeabi-v7aAPP_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);    }    }

 

android JNI學習之一

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.