開發工具:Eclipses
要進行NDK開發,先配置好開發環境,分爲以下兩項:
1.Android NDK
提供編譯腳本和工具.
2.Cygwin
完成Linux環境下的交叉編譯,將C/C++的源代碼文件編譯成Android系統可調用的共享連接庫文件.
兩者我都打包放在這兒了:
鏈接:AndroidNDK及Cygwin 密碼:i8yy
環境搭建OK了,現在開始新建一個小Demo測試下:
如上圖,基本重要的幾個文件都用紅框標示出來了.
libs文件夾不用手動創建,是完成編譯後自動生成的,用Refresh刷新就出現在其中了.
先把界面和基本功能OK.
package com.example.androidndkdemo;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class AndroidNdkDemoActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_android_ndk_demo);
final TextView displayLable = (TextView)findViewById(R.id.display);
Button button = (Button)findViewById(R.id.add_btn);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
double randomDouble = Math.random();
long x = Math.round(randomDouble * 100);
randomDouble = Math.random();
long y = Math.round(randomDouble * 100);
//System.loadLibrary("add-module"); //動態加載鏈接庫
long z = add(x, y);
String msg = x + "+" + y + "=" +z;
displayLable.setText(msg);
}
});
}
//public native long add(long x, long y); //鏈接庫中函數的聲明
public long add(long x, long y) {
return x + y;
}
}
也可以通過如下方式靜態加載鏈接庫
static{
System.loadLibrary("add-module");
}
佈局文件如下
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<TextView
android:id="@+id/display"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/hello_world"
android:textSize = "30dp" />
<Button
android:id="@+id/add_btn"
android:layout_below="@id/display"
android:layout_alignLeft="@id/display"
android:layout_width="100dp"
android:layout_height="100dp"
android:text="加法運算"
/>
</RelativeLayout>
然後創建Android.mk文件,內容如下:
LOCAL_PATH := $(call my-dir) //my-dir表示Android.mk所在的jni目錄, LOCAL_PATH用來定義需要編譯的C/C++源碼的位置
include $(CLEAR_VARS) //表示清空所有以LOCAL_開頭的變量,但不包括第一行的LOCAL_PATH,因爲所有變量都是全局變量,所以每次使用前必須清空所有以前用過的變量
LOCAL_MODULE := add-module //用來聲明模塊名稱,名稱必須唯一且不能存在空格,如本例中最後生成的鏈接庫文件名爲libadd-module.so,如果使用以lib爲前綴的模塊名稱,則最後生成的.so文件不會再添加lib前綴
LOCAL_SRC_FILES := add-module.c //表示編譯模塊所需要的C/C++文件
include $(BUILD_SHARED_LIBRARY) //表示Android NDK編譯系統需要構建共享庫,如果把BUILD_SHARED_LIBRARY改爲BUILD_STATIC_LIBRARY則表示需要NDK編譯系統構建靜態庫.共享庫可以被Android工程中的Java代碼調用,並打包到apk文件中;靜態庫只能在生成共享庫的過程中被共享庫中的C/C++代碼所調用
然後建立C源碼文件
#include <jni.h>
jlong Java_com_example_androidndkdemo_AndroidNdkDemoActivity_add(JNIEnv * env, jobject this, jlong x, jlong y)
{
return x + y;
}
jlong表示java長型整數,com_example_androidndkdemo_AndroidNdkDemoActivity_add表示包名_類名_函數名
最後一步,編譯共享庫模塊
首先啓動Cygwin,切換到Android NDK的主目錄下
輸入命令 export NDK=/cygdrive/d/android-ndk-r16b/
表示把右邊的路徑賦值給NDK變量
可以通過命令 echo $NDK 查看NDK的值
切換到Android項目的路徑下
輸入命令 $NDK/ndk-build
編譯成功的提示信息如下
然後再Eclipses的AndroidNdkDemo右鍵點擊Refresh就有libs文件夾了.
把AndroidNdkDemoActivity中java寫的add函數註釋掉,把原本註釋的兩處都取消註釋,運行app,看效果嘍.
我驗證是和用java寫的add函數一樣的效果,你要是什麼地方報錯了歡迎在評論區討論.
完整項目源碼在這兒: