Android Studio開發JNI工程
轉載來自:http://blog.csdn.net/sodino/article/details/41946607
使用Android Sutdio創建一個新的工程后,接下來記錄創建NDK工程的基本步驟。
本文將達到:
1. 創建NDK工程
2. 在JNI中輸出Log語句
3. 指定編譯的so庫的abi版本
4. 解決在創建NDK工程中的問題
Step: 1. 添加native接口
注意寫好native接口和System.loadLibrary()即可了,并無特別之處。
P.S:onCreate()中對R.id.txt執行setText(),所以這里需要對xml布局文件按正常的開發步驟進行修改即可。
直接給出代碼如下:
- public class MainActivity extends Activity{
- static {
- System.loadLibrary("JniTest");
- }
- public native String getStringFromNative();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- TextView txtView = (TextView) findViewById(R.id.txt);
- txtView.setText(getStringFromNative());
- }
- }
Step: 2.執行Build->Make Project</span>
這一步驟執行一下,驗證工程中并無其它錯誤,并對工程進行了編譯,生成了.class文件.
.class文件的生成路徑是在 app_path/build/intermediates/classes/debug下的.如下圖:
Step: 3.javah生成c頭文件
點擊"View->Tool Windows->Terminal",即在Studio中進行終端命令行工具.執行如下命令生成c語言頭文件。
這里需要注意的是要進入 <Project>\app\src\main的目錄下執行javah命令,為的是生成的 .h 文件同樣是在<Project>\app\src\main路徑下,可以在Studio的工程結構中直接看到。
操作命令:
javah -d jni -classpath <SDK_android.jar>;<APP_classes> lab.sodino.jnitest.MainActivity
具體操作圖如下:
[java]
view plain copy

</div>
</div>
- javah -d jni -classpath c:\Users\sodinochen\AppData\Local\Android\sdk\platforms
- \android-16\android.jar;..\..\build\intermediates\classes\debug lab.sodino.jnitest.MainActivity
</div>
對于"主版本51比50新,此編譯器支持最新的主版本"則是由于電腦上安裝了兩個版本的jdk引起的,而當前使用的是舊的jdk。
把舊的jdk刪除,并執行java version命令后顯示當前jdk為最新的1.7時,則不會再有此提示了。如下圖:
最后的生成結果:
Step: 4.編輯c文件
在main.c文件中實現頭文件中的方法,具體功能為直接return回一個String,并且使用android_log打印出相關日志。
代碼如下:
[cpp]
view plain copy

</div>
</div>
- /* DO NOT EDIT THIS FILE - it is machine generated */
- #include <jni.h>
- #include <android/log.h>
- #ifndef LOG_TAG
- #define LOG_TAG "ANDROID_LAB"
- #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
- #endif
- /* Header for class lab_sodino_jnitest_MainActivity */
- #ifndef _Included_lab_sodino_jnitest_MainActivity
- #define _Included_lab_sodino_jnitest_MainActivity
- #ifdef __cplusplus
- extern "C" {
- #endif
- /*
- * Class: lab_sodino_jnitest_MainActivity
- * Method: getStringFromNative
- * Signature: ()Ljava/lang/String;
- */
- JNIEXPORT jstring JNICALL Java_lab_sodino_jnitest_MainActivity_getStringFromNative
- (JNIEnv * env, jobject jObj){
- LOGE("log string from ndk.");
- return (*env)->NewStringUTF(env,"Hello From JNI!");
- }
- #ifdef __cplusplus
- }
- #endif
- #endif
</div>
</div>
到這里后,我們再執行一個"Build->Make Project",發現"Messages Gradle Build"會給出提示如下:
[java]
view plain copy
sesese色

</div>
</div>
- Error:Execution failed for task ':app:compileDebugNdk'.
- > NDK not configured.
- Download the NDK from http://developer.android.com/tools/sdk/ndk/.Then add ndk.dir=path/to/ndk in local.properties.
- (On Windows, make sure you escape backslashes, e.g. C:\\ndk rather than C:\ndk)
</div>
</div>
這里提示了NDK未配置,并且需要在工程中的local.properties文件中配置NDK路徑。好了,提示很清楚了,那我們就進入下一步吧。
Step: 5.配置NDK
這一步包括兩個動作:
1.指明ndk路徑

2. 修改build.gradle配置
工程中共有兩個build.gradle配置文件,我們要修改的是在<Project>\app\build.gradle這個文件。為其在defaultConfig分支中增加上
[java]
view plain copy

</div>
</div>
<ol start="1" class="dp-j" style="padding:0px;border:0px;list-style-position:initial;color:#5c5c5c;margin:0px 0px 1px 45px!important;background-color:#ffffff;">
<li class="alt" style="border-width:0px 0px 0px 3px;border-left-style:solid;border-left-color:#6ce26c;list-style:decimal-leading-zero outside;color:inherit;line-height:18px;margin:0px!important;padding:0px 3px 0px 10px!important;"> <span style="margin:0px;padding:0px;border:0px;color:black;background-color:inherit;"><span style="margin:0px;padding:0px;border:0px;background-color:inherit;">ndk { </span></span></li>
<li style="border-width:0px 0px 0px 3px;border-left-style:solid;border-left-color:#6ce26c;list-style:decimal-leading-zero outside;line-height:18px;margin:0px!important;padding:0px 3px 0px 10px!important;background-color:#f8f8f8;"> <span style="margin:0px;padding:0px;border:0px;color:black;background-color:inherit;"> moduleName <span class="string" style="margin:0px;padding:0px;border:0px;color:blue;background-color:inherit;">"JniTest"</span><span style="margin:0px;padding:0px;border:0px;background-color:inherit;"> </span></span></li>
<li class="alt" style="border-width:0px 0px 0px 3px;border-left-style:solid;border-left-color:#6ce26c;list-style:decimal-leading-zero outside;color:inherit;line-height:18px;margin:0px!important;padding:0px 3px 0px 10px!important;"> <span style="margin:0px;padding:0px;border:0px;color:black;background-color:inherit;"> ldLibs <span class="string" style="margin:0px;padding:0px;border:0px;color:blue;background-color:inherit;">"log"</span><span style="margin:0px;padding:0px;border:0px;background-color:inherit;">, </span><span class="string" style="margin:0px;padding:0px;border:0px;color:blue;background-color:inherit;">"z"</span><span style="margin:0px;padding:0px;border:0px;background-color:inherit;">, </span><span class="string" style="margin:0px;padding:0px;border:0px;color:blue;background-color:inherit;">"m"</span><span style="margin:0px;padding:0px;border:0px;background-color:inherit;"> </span></span></li>
<li style="border-width:0px 0px 0px 3px;border-left-style:solid;border-left-color:#6ce26c;list-style:decimal-leading-zero outside;line-height:18px;margin:0px!important;padding:0px 3px 0px 10px!important;background-color:#f8f8f8;"> <span style="margin:0px;padding:0px;border:0px;color:black;background-color:inherit;"> abiFilters <span class="string" style="margin:0px;padding:0px;border:0px;color:blue;background-color:inherit;">"armeabi"</span><span style="margin:0px;padding:0px;border:0px;background-color:inherit;">, </span><span class="string" style="margin:0px;padding:0px;border:0px;color:blue;background-color:inherit;">"armeabi-v7a"</span><span style="margin:0px;padding:0px;border:0px;background-color:inherit;">, </span><span class="string" style="margin:0px;padding:0px;border:0px;color:blue;background-color:inherit;">"x86"</span><span style="margin:0px;padding:0px;border:0px;background-color:inherit;"> </span></span></li>
<li class="alt" style="border-width:0px 0px 0px 3px;border-left-style:solid;border-left-color:#6ce26c;list-style:decimal-leading-zero outside;color:inherit;line-height:18px;margin:0px!important;padding:0px 3px 0px 10px!important;"> <span style="margin:0px;padding:0px;border:0px;color:black;background-color:inherit;">} </span></li>
</ol>
</div>
</div>
以上配置代碼指定的so庫名稱為JniTest,鏈接時使用到的庫,對應android.mk文件中的LOCAL_LDLIBS,及最終輸出指定三種abi體系結構下的so庫。
添加后如下圖:
</div>
這時,再執行"Build->Rebuild Project",就可以編譯出so文件了。
但在Window平臺上會出現一個問題:
[java]
view plain copy
Step: 5.配置NDK
編譯出來的庫文件被Studio輸出到了下圖的路徑中

</div>
</div>
- Error:Execution failed for task ':app:compileDebugNdk'.
- > com.android.ide.common.internal.LoggedErrorException: Failed to run command:
- D:\Mission\adt-bundle-windows\ndk-r10b\ndk-build.cmd NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\Android.mk APP_PLATFORM=android-21 NDK_OUT=C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\obj NDK_LIBS_OUT=C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\lib APP_ABI=armeabi,armeabi-v7a,x86
- Error Code:
- 2
- Output:
- make.exe: *** No rule to make target `C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\obj/local/armeabi/objs/JniTest/C_\Users\sodinochen\AndroidstudioProjects\JniTest2\app\src\main\jni', needed by `C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\obj/local/armeabi/objs/JniTest/C_\Users\sodinochen\AndroidstudioProjects\JniTest2\app\src\main\jni\main.o'. Stop.
</div>
</div>
出現這個錯誤很莫名其妙..幾番折騰下,找到一個視頻出來了大概原因及解決方式:
出處見油Tube視頻 02:50分開始:
https://www.油Tube.com/watch?v=okLKfxfbz40#t=362
在Windows下NDK一個bug,當僅僅編譯一個文件時出現會出現此問題,解決方法就是
再往jni文件夾加入一個空util.c文件即可。如下圖:

</div>
編譯出來的庫文件被Studio輸出到了下圖的路徑中
Step: 6.安裝運行
界面:
查看Log打印:
轉載來自:http://blog.csdn.net/sodino/article/details/41946607
使用Android Sutdio創建一個新的工程后,接下來記錄創建NDK工程的基本步驟。
本文將達到:
1. 創建NDK工程
2. 在JNI中輸出Log語句
3. 指定編譯的so庫的abi版本
4. 解決在創建NDK工程中的問題
Step: 1. 添加native接口
注意寫好native接口和System.loadLibrary()即可了,并無特別之處。
P.S:onCreate()中對R.id.txt執行setText(),所以這里需要對xml布局文件按正常的開發步驟進行修改即可。
直接給出代碼如下:
- public class MainActivity extends Activity{
- static {
- System.loadLibrary("JniTest");
- }
- public native String getStringFromNative();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- TextView txtView = (TextView) findViewById(R.id.txt);
- txtView.setText(getStringFromNative());
- }
- }
Step: 2.執行Build->Make Project
這一步驟執行一下,驗證工程中并無其它錯誤,并對工程進行了編譯,生成了.class文件.
.class文件的生成路徑是在 app_path/build/intermediates/classes/debug下的.如下圖:

Step: 3.javah生成c頭文件
點擊"View->Tool Windows->Terminal",即在Studio中進行終端命令行工具.執行如下命令生成c語言頭文件。
這里需要注意的是要進入 <Project>\app\src\main的目錄下執行javah命令,為的是生成的 .h 文件同樣是在<Project>\app\src\main路徑下,可以在Studio的工程結構中直接看到。
操作命令:
javah -d jni -classpath <SDK_android.jar>;<APP_classes> lab.sodino.jnitest.MainActivity
具體操作圖如下:

- javah -d jni -classpath c:\Users\sodinochen\AppData\Local\Android\sdk\platforms
- \android-16\android.jar;..\..\build\intermediates\classes\debug lab.sodino.jnitest.MainActivity
對于"主版本51比50新,此編譯器支持最新的主版本"則是由于電腦上安裝了兩個版本的jdk引起的,而當前使用的是舊的jdk。
把舊的jdk刪除,并執行java version命令后顯示當前jdk為最新的1.7時,則不會再有此提示了。如下圖:

最后的生成結果:
Step: 4.編輯c文件
在main.c文件中實現頭文件中的方法,具體功能為直接return回一個String,并且使用android_log打印出相關日志。
代碼如下:
- /* DO NOT EDIT THIS FILE - it is machine generated */
- #include <jni.h>
- #include <android/log.h>
- #ifndef LOG_TAG
- #define LOG_TAG "ANDROID_LAB"
- #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
- #endif
- /* Header for class lab_sodino_jnitest_MainActivity */
- #ifndef _Included_lab_sodino_jnitest_MainActivity
- #define _Included_lab_sodino_jnitest_MainActivity
- #ifdef __cplusplus
- extern "C" {
- #endif
- /*
- * Class: lab_sodino_jnitest_MainActivity
- * Method: getStringFromNative
- * Signature: ()Ljava/lang/String;
- */
- JNIEXPORT jstring JNICALL Java_lab_sodino_jnitest_MainActivity_getStringFromNative
- (JNIEnv * env, jobject jObj){
- LOGE("log string from ndk.");
- return (*env)->NewStringUTF(env,"Hello From JNI!");
- }
- #ifdef __cplusplus
- }
- #endif
- #endif
到這里后,我們再執行一個"Build->Make Project",發現"Messages Gradle Build"會給出提示如下:
- Error:Execution failed for task ':app:compileDebugNdk'.
- > NDK not configured.
- Download the NDK from http://developer.android.com/tools/sdk/ndk/.Then add ndk.dir=path/to/ndk in local.properties.
- (On Windows, make sure you escape backslashes, e.g. C:\\ndk rather than C:\ndk)
這里提示了NDK未配置,并且需要在工程中的local.properties文件中配置NDK路徑。好了,提示很清楚了,那我們就進入下一步吧。
這一步包括兩個動作:
1.指明ndk路徑

2. 修改build.gradle配置
工程中共有兩個build.gradle配置文件,我們要修改的是在<Project>\app\build.gradle這個文件。為其在defaultConfig分支中增加上
- ndk {
- moduleName "JniTest"
- ldLibs "log", "z", "m"
- abiFilters "armeabi", "armeabi-v7a", "x86"
- }
以上配置代碼指定的so庫名稱為JniTest,鏈接時使用到的庫,對應android.mk文件中的LOCAL_LDLIBS,及最終輸出指定三種abi體系結構下的so庫。
添加后如下圖:

這時,再執行"Build->Rebuild Project",就可以編譯出so文件了。
但在Window平臺上會出現一個問題:
- Error:Execution failed for task ':app:compileDebugNdk'.
- > com.android.ide.common.internal.LoggedErrorException: Failed to run command:
- D:\Mission\adt-bundle-windows\ndk-r10b\ndk-build.cmd NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\Android.mk APP_PLATFORM=android-21 NDK_OUT=C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\obj NDK_LIBS_OUT=C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\lib APP_ABI=armeabi,armeabi-v7a,x86
- Error Code:
- 2
- Output:
- make.exe: *** No rule to make target `C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\obj/local/armeabi/objs/JniTest/C_\Users\sodinochen\AndroidstudioProjects\JniTest2\app\src\main\jni', needed by `C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\obj/local/armeabi/objs/JniTest/C_\Users\sodinochen\AndroidstudioProjects\JniTest2\app\src\main\jni\main.o'. Stop.
出現這個錯誤很莫名其妙..幾番折騰下,找到一個視頻出來了大概原因及解決方式:
出處見油Tube視頻 02:50分開始:
https://www.油Tube.com/watch?v=okLKfxfbz40#t=362
在Windows下NDK一個bug,當僅僅編譯一個文件時出現會出現此問題,解決方法就是
再往jni文件夾加入一個空util.c文件即可。如下圖:

Step: 6.安裝運行
界面:
查看Log打印:
本文由用戶 zdrn4631 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!