在前面講了基礎配置,那麼接下來開始使用了:
第一個native方法
在第一篇中配置完cmake後,筆者在MainActivity中創建來了一個native方法:
package shixin.ndkdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
/**
* 引入動態庫,這裏與cmake中的一致: my_native_lib
*/
static {
System.loadLibrary("my_native_lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(intFromJni() + "");
}
/**
* 從jni獲取int返回
* @return int值
*/
public native int intFromJni();
}
在創建native方法之後,會提示錯誤,筆者的AndroidStudio是3.2版本了,支持比較好了,直接像我們平時根據提示自動修復錯誤一樣,它就會創建一個原生方法在cpp文件中了。
比如這裏是:native-lib.cpp文件,與cmake配置的代碼源文件一樣,如果不是你可以手動移動一下到native-lib.cpp中,或者將新的cpp文件也鏈接到cmake配置文件中,只要能識別到,靈活處理即可。
#include <jni.h>
/**
* 自動生成的方法
*/
extern "C"
JNIEXPORT jint JNICALL
Java_shixin_ndkdemo_MainActivity_intFromJni(JNIEnv *env, jobject instance) {
jint age = 5;
//返回5
return age;
}
最後的執行效果,就是textview顯示的“5”
基礎知識
咱們編譯運行後,c裏面的代碼是和java一樣運行的嗎?肯定不是,如果是的話就不用這麼大費周章來個jni調用原生了,實際編譯後生成的就是我們平時用的很多的so動態庫。
一. 原生庫
Android中日常我們使用的原生庫,都是以so的形式提供的,咱們使用編譯後也是so動態庫
可以查看下編譯成的so,目錄:
build/intermediates/cmake/debug/obj
- so 介紹
abi :aplication Binary Interface,前面的arm代表arm平臺,v7a,-8a代表對應的CPU架構
編譯各個平臺使用的是ndk目錄下的工具鏈:Android/sdk/ndk-bundle/toolchains