JNI method

 

package com.example.register;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {
    private static final String TAG = "HTC+++";

    public int age;

    static {
        System.loadLibrary("hello-jni");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initData();
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(this);
    }

    private void initData() {
        age = 10;
    }

    private void calledByNative() {
        Log.d(TAG, "java layer: called By Native");
    }

    private static void staticMethod(int value) {
        Log.d(TAG, "java layer: static method called By Native. value: "
                + value);
    }

    private int multi(int a, int b) {
        return a * b;
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button:
                print("I want to print");
                int result = add(123, 456);
                Log.d(TAG, "123 + 456 = " + result);
                String s = getString();
                Log.d(TAG, "getString() = " + s);
                callJava();
                changeintField(111);
                Log.d(TAG, "age:" + age);
                break;
            default:
                break;
        }

    }

    private native void print(String str);

    private native int add(int a, int b);

    private native String getString();

    private native void callJava();

    private native void changeintField(int value);
}

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context="${relativePackage}.${activityClass}" >

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="xxxx" />

</LinearLayout>

 

// jni/Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello-jni LOCAL_SRC_FILES := dynamic_jni.c \ static_jni.c LOCAL_LDLIBS :=-llog include $(BUILD_SHARED_LIBRARY)

 

// jni/Application.mk
APP_ABI := all

 

// jni/dynamic_jni.c
#include <string.h> #include <jni.h> #include <android/log.h> #define LOG_TAG "HTC+++" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__) void callJavaMethod(JNIEnv *env, jobject thiz) { jclass cls = (*env)->GetObjectClass(env, thiz); jmethodID methodId = (*env)->GetMethodID(env, cls, "calledByNative", "()V"); (*env)->CallVoidMethod(env, thiz, methodId); jmethodID staticMethod = (*env)->GetStaticMethodID(env, cls, "staticMethod", "(I)V"); (*env)->CallStaticVoidMethod(env, cls, staticMethod, 999); jmethodID multiMethod = (*env)->GetMethodID(env, cls, "multi", "(II)I"); jint result = (*env)->CallIntMethod(env, thiz, multiMethod, 100, 200); LOGD("multi: 100 * 200 = %d", result); } void changeIntField(JNIEnv *env, jobject thiz, jint newValue) { jclass cls = (*env)->GetObjectClass(env, thiz); jfieldID fieldId = (*env)->GetFieldID(env, cls, "age", "I"); jint age = (*env)->GetIntField(env, thiz, fieldId); LOGD("Native: current age:%d", age); (*env)->SetIntField(env, thiz, fieldId, newValue); } void nativePrint(JNIEnv *env, jobject thiz, jstring jstr) { const char *nativeString = (*env)->GetStringUTFChars(env, jstr, 0); LOGD("nativePrint() String:%s", nativeString); //java中有垃圾回收机制,而c语言没有,那么使用完该字符串之后该如何处理呢? //字符串str使用完后,需要通知虚拟机平台相关代码无需再访问 //如果是中文则需要转码 (*env)->ReleaseStringUTFChars(env, jstr, nativeString); } jint nativeAdd(JNIEnv *env, jobject thiz, jint a, jint b) { return a + b; } /* jstring newString(JNIEnv *env, jobject thiz) { return (*env)->NewStringUTF(env, "Hello from JNI !"); } */ static JNINativeMethod gMethods[] = { {"print", "(Ljava/lang/String;)V", (void*) nativePrint }, {"add", "(II)I", (void*) nativeAdd }, // {"getString", "()Ljava/lang/String;", (void*) newString }, {"callJava", "()V", (void*) callJavaMethod }, {"changeintField", "(I)V", (void*) changeIntField } }; static int registerMethods(JNIEnv * env) { jclass clazz = (*env)->FindClass(env, "com/example/register/MainActivity"); int size = sizeof(gMethods) / sizeof(gMethods[0]); if ((*env)->RegisterNatives(env, clazz, gMethods, (jint) size) != JNI_OK) { return -1; } return 0; } jint JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv* env = NULL; if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) { return -1; } if (registerMethods(env) != 0) { return -1; } return JNI_VERSION_1_4; }

 

// static_jni.c
#include <string.h> #include <jni.h> #include <android/log.h> #define LOG_TAG "MainActivity" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__) jstring Java_com_example_register_MainActivity_getString(JNIEnv* env, jobject thiz) { return (*env)->NewStringUTF(env, "Hello from static JNI !"); }

 

posted @ 2015-10-28 20:50  牧 天  阅读(319)  评论(0)    收藏  举报