概述
1. 什么是JNI
- JNI java native interface native本地 java本地接口
- 通過JNI可以實現java和本地代碼之間相互調用
- jni可以看做是翻譯 實際上就是一套協議
2. 為什么要用JNI
- 市場需求
- 讓java代碼和底層代碼之間互相調用
- java調用底層特殊硬件(調用c語言,車載電腦)
- 效率上c/c++語言效率更高(時間和內存要求嚴格的場景)
- 復用已經存在的c代碼, c語言發展了幾十年有很多優秀的代碼庫(ffmpeg,opencv,7zip)
- java反編譯非常容易.c語言反編譯不容易.關鍵業務邏輯需要用c實現.
- 歷史遺留問題,復用原來pc端的c代碼
jni的簡單使用
工具:eclipse,NDK
1.首先在eclipse中新建一個項目
jniimg1.jpg
2.在MainActivity中用native聲明一個方法,用native關鍵字說明其修飾的方法是一個原生態方法,方法對應的實現不是在當前文件,而是在用其他語言(如C和C++)實現的文件中.
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public native void callC();
}
3.在工程目錄下創建一個jni文件夾,并創建一個c文件,并在c文件中寫c代碼
jniimg2.jpg
#include <jni.h>
#include<stdio.h>
#include<stdlib.h>
JNIEXPORT jstring JNICALL Java_com_example_hellofromc_MainActivity_callC
(JNIEnv * env, jobject obj) {
char* arr = "hello fromC!!!";
return (*env)->NewStringUTF(env, arr);
}
4.配置c代碼編譯的腳本文件 Android.mk文件
在jni文件夾里新建一個Android.mk文件,寫上代碼
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := callC
LOCAL_SRC_FILES := callC.c
include $(BUILD_SHARED_LIBRARY)
5.在java代碼里面寫靜態代碼塊
public class MainActivity extends Activity {
==static{
System.loadLibrary("callC");
}==
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public native void callC();
}
6.像使用一般java方法一樣調用native的方法.
public class MainActivity extends Activity {
static{
System.loadLibrary("callC");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//這里就打印一個吐司進行測試
Toast.makeText(this, callC(),0).show();
}
public native String callC();
}
7.完成
jniimg3.gif