標籤:android ndk jni native android-mk
Android NDK:②第一個NDK程式(建立步驟&一些問題)
本節內容是:示範搭建第一個NDK程式
- Android NDK第一個NDK程式建立步驟一些問題
- 建立一個Android Project
- Java代碼中聲明native方法
- 建立Jni檔案夾編寫ccpp代碼
- 為項目添加NDK支援
- 建立配置一個Builder
- 調用了native方法的地方載入庫
- 好了把程式跑起來
- 總結
- 遇到的問題
1.建立一個Android Project
直接建立一個新的Android Application Project即可~
2.Java代碼中聲明native方法:
package com.jay.example.firstndk;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;public class MainActivity extends Activity { private Button btnShow; // 聲明native方法 public native String javaFromJNI(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnShow = (Button) findViewById(R.id.btnShow); btnShow.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, javaFromJNI(), Toast.LENGTH_SHORT).show(); } }); }}
3.建立Jni檔案夾,編寫c/cpp代碼
這裡要注意的地方有兩個:
①傳回值類型
jni.h檔案中中事先定義的資料類型,我們可以在ndk/platforms/android-xx/arch-arm/user/include目錄下找到,~xx代表版本號碼
開啟jni.h我們會看到很多資料類型,我們這裡的是string:
②方法名:按照下述規則:
傳回值類型 Java_包名_類名_native方法名(JNIEnv* env, jobject obj)
而裡頭的參數是固定的,在jni.h檔案我們也可以查到,他是一個叫做JNINativeInterface的結構體,結構體中定義了很多資料類型,我們找到那個返回字串的:
好的,那麼接下來我們把我們的c代碼寫完,我們在jni目錄下建立一個叫first.c的檔案:
#include<stdio.h> #include<jni.h> jstring Java_com_jay_example_firstndk_MainActivity_javaFromJNI(JNIEnv* env, jobject obj) { return (*env)->NewStringUTF(env, "First Blood~");}
4.為項目添加NDK支援
工程右鍵->Android Tools ->Add Native Support輸入so庫名稱:
自己給so庫命名:
這個時候會看到,jni目錄下除了我們自己編寫的c檔案外,還多了兩個東東,xx.cpp和Android.mk檔案,那個cpp可以直接刪掉,接著開啟Android.mk件,修改下東西:
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := FirstNDKLOCAL_SRC_FILES := first.cinclude $(BUILD_SHARED_LIBRARY)
ps:其實這步可以直接在3就進行,會直接產生一個.cpp與Android.mk的檔案的~
5.建立&配置一個Builder
右鍵Project->Properties->Builders->New,建立一個Builder,在彈出的對話方塊上面點擊Program,OK!
雙擊開啟,進行配置:
點擊確定,OK,好了,接下來就可以自定編譯代碼了~比如我們修改代碼後儲存,他都會重新編譯下.so
6.調用了native方法的地方載入庫:
7.好了,把程式跑起來~
8.總結:
好了,第一個NDK程式就這樣完成了,中途磕磕碰碰遇到很多問題,總算是順利地跑起來了,下面歸納下大概步驟:
- 建立一個普通NDK工程
- 聲明native方法
- 建立Jni檔案夾,可以自己寫個.c或者.cpp檔案,或者直接第四步直接產生一個.cpp與Android.mk檔案
- 為項目添加NDK支援
- 建立&配置一個Builder
- 調用了native方法的地方載入庫(System.loadLibrary(xxx))
- 運行程式~~
好了,大概過程就如上面所述~可能還有其他快捷的建立方法吧,後續遇到的話在給大家介紹哈~最後附上弄這個程式時遇到的一些問題以及解決方案!
9.遇到的問題
1.運行後程式直接死掉- -,後來查log發現是c那裡方法名寫錯了,直接報方法找不到!
解決方案:嚴格按照下述規定寫
傳回值類型 Java_包名_類名_native方法名(JNIEnv* env, jobject obj)
2.出現這樣的提示:
Android NDK: WARNING: APP_PLATFORM android-17 is larger than android:minSdkVersion 14 in ./AndroidManifest.xml
解決方案:
android-ndk-r8e/build/core/add-application.mk第128行把__ndk_warning改為__ndk_info;然後重新build一次項目即可消除錯誤。
或者,直接寫成這樣…我們公司是這樣做的…感覺這樣雖然不報錯,但是不好…
3.用c來寫的出現:Method ‘NewStringUTF’ could not be resolved
就是找不到方法,真奇葩…
解決方案:
比如我的路徑是:
E:\NDK\android-ndk-r10d\platforms\android-17\arch-arm\usr\include
4.如果你用的是.cpp的話,出現3的問題
解決方案:為供Java調用的c++函數前加入extern “C” 修飾
另外輸出字串的語句也是不一樣的:
(*env)->Method(env, XXX)改成env->Method(XXX)即可.
Android NDK:②第一個NDK程式(建立步驟&一些問題)