AndroidStudio之JNI開發
從事android開發也有一兩年時間了,一直做的是跟硬件相關的Android開發,本人仍算是技術小白一個,之前使用Eclipse短暫的一段時間,學習過怎麼用來編譯C文件,使用jni。但是有點麻煩,而且項目中使用較少,也就淡忘遺棄了。用Android Studio一年多了,發現自己並不熟悉怎麼使用jni,在此做個筆記,雖不完善,也夠自己實現使用,大神勿噴。
創建項目
首先創建一個演示用的ndkdemo程序。
MainActivity.java
主要界面,顯示從C文件調用的函數,得到的字符串。
public class MainActivity extends AppCompatActivity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.tv);
//通過java方法,調用native
NdkUtils ndkUtils = new NdkUtils();
textView.setText(ndkUtils.getString());
}
}
NdkUtils.java
public class NdkUtils {
//native方法,調用C文件內的方法。該方法爲其他java文件調用,而在C文件中要對應本方法的完整類名,路徑名,方法名,
public native String getString();
//靜態加載類庫,這樣才能正確使用C文件的方法,否則報錯。
static {
System.loadLibrary("ndk");//ndk爲加載的so庫文件名,在app/name.gradle裏面配置,若是defaultConfig沒有配置ndk{...},有C文件,也是可以的,但是這個加載是必須的。可以不寫"ndk"。
}
}
ndk.gradle
android {
...
defaultConfig{
...
defaultConfig{
...
ndk{
moduleName"ndk"//這是生成so文件的文件名,當然它會自動前面加上lib三個字母,不作爲文件名的哦。如果此處不配置這段話,有C文件,也是可以直接用的。只是不生成so文件了。生成的so文件在app\build\intermediates\moduleName下的debug\lib或者obj裏面。
}
}
...
}
gradle.properties
這句話使用與聲明調用C文件的方式,若是不寫的話,就會報錯,說什麼沒有ndk或者cmake來編譯C文件之類的錯。
android.useDeprecatedNdk=true
生成.h文件和C文件
如上面初步寫好demo文件後,運行Build,AndroidStudio編譯java文件,在左側Project視圖下,app\build\intermediates\classes\debug文件夾下,有android和com兩個文件夾,com下是包名和java的class文件。
用Terminal切換到上述目錄下,運行命令
javah-jni com.pkgname.NdkUtils
這時候就會在該目錄下生成一個.h
的文件。在src/mian/下面創建
jni
文件夾,copy上面的.h
文件到jni
文件夾下。創建c文件,在jni目錄下。==切記,本文爲了隱去個人姓名,用pkgName代表報名,小白可別直接照抄啊,呵呵。==
#include <com_pdkname_NdkUtils.h> /** * 簡單寫一個c文件函數,返回一個字符串,注意函數名的格式,是上述java文件的getString方法的包名+方法名的格式。 */ JNIEXPORT jstring JNICALL Java_com_pkgName_NdkUtils_getString(JNIEnv *env,jobject obj){ return (*env) -> NewString(env,"調用jni,從C文件返回字符串。"); }
**附註:**Android Studio2.2版本的,jdk1.8,ndk也是AndroidStudio附帶最新的,記住要在工程裏面配置好jdk和ndk哦。