一.NDK介绍:
1.定义:
Native Development Kit 是Android 的一种的开发工具包
2.作用:
快速开发C, C++的动态库,并自动将so和应用一起打包APK,即可通过NDK在Android中使用JNI与本地代码(如:C, C++)交互
3,优点:
1.运行效率高
2.代码安全
3.跨平台
二.JNI的介绍:
1.定义:
JAVA Native Interface
JNI是一种协议
2.作用:
通过JNI能使java和c++相互调用
三.静态注册:
操作:
终端切换到 …/xxx项目/app/src/main/java下执行:
javah -jni -encoding UTF-8 com.tencent.jnipro.MainActivity
此时在 …/xxx项目/app/src/main/java下生成一个文件com_tencent_jnipro_MainActivity.h
如题:
2.在…/…项目/下创建文件夹jni并将上述生成的com_tencent_jnipro_MainActivity.h复制其中并分别编写Android.mk Application.mk 和 jnipro.c内容如下(注意:Android.mk 和 Application.mk两文件名字固定)如图
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := jinpro #模块名
LOCAL_SRC_FILES := jnipro.c #源文件.c或.cpp
LOCAL_ARM_MODE := arm #编译后的指令集ARM指令
LOCAL_LDLIBS := -llog #依赖库
include $(BUILD_SHARED_LIBRARY) #指定编译文件的类型
Application.mk
APP_ABI := armeabi-v7a
jnipro.c
//
//
//
#include<jnipro.h>
JNIEXPORT jstring JNICALL Java_com_tencent_jnipro_MainActivity__1getString
(JNIEnv * env, jobject obj){
jstring str =(*env)-> NewStringUTF(env, "hello worlads");
return str;
}
//获取java中普通字段并且返回
JNIEXPORT jstring JNICALL Java_com_tencent_jnipro_MainActivity__1getPro
(JNIEnv * env, jobject obj){
//获取类
jclass clazz = (*env) -> FindClass(env, "com/tencent/jnipro/MainActivity");
//获取字段id
jfieldID _fieldID = (*env) -> GetFieldID(env, clazz, "pro", "Ljava/lang/String;");
//获取字段的值
jobject str = (*env) -> GetObjectField(env, obj, _fieldID);
return str;
}
//获取java当中的静态字段,并且返回
JNIEXPORT jstring JNICALL Java_com_tencent_jnipro_MainActivity__1getStaticPro
(JNIEnv * env, jobject obj){
jclass clazz = (*env) -> FindClass(env, "com/tencent/jnipro/MainActivity");
//获取静态字段的id
jfieldID _fieldID = (*env)-> GetStaticFieldID(env, clazz, "staticPro", "Ljava/lang/String;");
jobject str = (*env) -> GetStaticObjectField(env, clazz, _fieldID);
return str;
}
//调用java当中的普通方法和静态方法
JNIEXPORT void JNICALL Java_com_tencent_jnipro_MainActivity__1javaToC
(JNIEnv * env, jobject obj){
jclass clazz = (*env) -> FindClass(env, "com/tencent/jnipro/MainActivity");
//获取普通方法的id
jmethodID _methodID = (*env) -> GetMethodID(env, clazz, "_method", "()V");
//调用java中普通方法
(*env) -> CallVoidMethod(env, obj, _methodID);
jmethodID _methodID1 = (*env) -> GetStaticMethodID(env, clazz, "_staticMethod", "()V");
//调用java中静态方法:
(*env) -> CallStaticVoidMethod(env, clazz, _methodID1);
}
注意:"Ljava/lang/String;"后的分号不能掉
3.生成.so文件
终端切换到…/项目/jni下执行
ndk-build
会在/项目/libs下生成armeabi-v7a/xxx.so文件,
将生成的的/armeabi-v7a/xxx.so文件复制到xxx/项目/app/libs下如图:
4.配置环境:
在xxx/项目/app/build.gradle文件中的android中添加代码:
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
MainActivity.java
package com.tencent.jnipro;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
private static Context context;
//普通字段
public String pro = "pro";
// //静态字段
public static String staticPro = "静态pro";
//
static {
System.loadLibrary("jinpro");
}
//普通方法
public void _method() {
Toast.makeText(this, "普通方法", Toast.LENGTH_LONG).show();
}
//
// //静态方法:
public static void _staticMethod() {
Toast.makeText(context, "静态方法", Toast.LENGTH_LONG).show();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, _getString(), Toast.LENGTH_SHORT).show();
Toast.makeText(this, _getPro(), Toast.LENGTH_LONG).show();
Toast.makeText(this, _getStaticPro(), Toast.LENGTH_LONG).show();
context = this;
_javaToC();
}
//java调用C;
private native String _getStaticPro();
//java 调用C;
private native String _getPro();
//java调用C;
public native void _javaToC();
//被native修饰的方法具体实现由C/C++来完成
private native String _getString();
}