开发工具: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函数一样的效果,你要是什么地方报错了欢迎在评论区讨论.
完整项目源码在这儿: