首页 > 代码库 > [ANT] Ant脚本封装ndk-build命令并执行打包启动
[ANT] Ant脚本封装ndk-build命令并执行打包启动
本篇文章为示范如何在Eclipse中开始一个Jni工程的操作步骤,并假设读者初步了解JNI具体规范及使用ANT脚本。(话说这样的初学者不多见吧…其实我只是想给自己写个总结而已)
阅读本文之前,请确保你的开发环境已经满足如下配置:
1. 设置好了Android Sdk及Ndk环境变量。
NDK的安装建议使用MinGW,只要能在命令行中正常运行make gcc程序即是成功了。并在EclipseàPreferencesàNDK填写NDK的本地路径。
2. 支持Ant脚本执行。
3. Eclipse中安装了CDT插件,可以直接编写C/C++代码。
编写Jni时改动C/C++代码,要执行编译并安装时经过的步骤为:
1. 执行ndk-build
2. Eclipse中启动编译apk并安装
但是我是个懒汉,在想只要进行一个操作就能安装开始调试了。所以为了更加方便,下面演示创建并编写Jni代码的步骤,在普通步骤结束后,会讲述如何使用一句命令行即可编译jni代码并打包生成apk,最后自动启动APK的Ant脚本。
创建工程TestJni,工程结构如下图。
对应的MainActivity.java的代码如下:
public class MainActivity extends Activity { protected voidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextViewtxt = (TextView)findViewById(R.id.txtJni); txt.setText(hello()); } public native Stringhello(); static{ System.loadLibrary("TestJni"); } }
接下来处理Jni的事情。
右击工程”TestJni”à” Android Tools” à” Add Native Support…”,在弹出的输入”Add Android Native Support”对话框中输入最终生成的so文件名为“TestJni”如下图。
这时工程结构也会新增加”jni”文件夹并自动生成了TestJni.cpp及Android.mk文件。即Eclipse默认生成C++文件,这与使用javah命令去生成的C头文件是不同的。如下图。
这时来个永恒的”HelloWorld”示例吧。TestJni.cpp文件中的C++代码如下:
#include <string.h> #include <jni.h> #ifdef__cplusplus extern "C" { #endif JNIEXPORT jstring JNICALL Java_lab_sodino_testjni_MainActivity_hello(JNIEnv * env, jobject thiz) { returnenv->NewStringUTF("HelloWorld!A string from JNI."); } #ifdef__cplusplus } #endif
代码中extern “C”{}的作用是C++编译的时候,会对函数名进行修饰以用于实现函数充载,而C里面没有这个,所以需要用extern “C”在对头文件进行声明的时候加以区分。这个用于链接的时候进行函数名查找。如果没有此句代码,编译出so文件并打包运行后,会导致java.lang.UnsatisfiedLinkError:Native method not found异常。
此时,在工程目录中执行命令行ndk-build,即生成so文件。工程结构变化如下图:然后在Eclipse中点击F11,即可自动完成打包及安装到手机或模拟器的工作。运行后效果图如下:
下面要讲述的是使用Ant脚本实现方便编译ndk-build并打包APK及安装到手机的实现方法。
在命令行模式下进入到该工程的目录中,并执行如下命令以生成build.xml脚本。
android updateproject -p . –s
这时工程目录结构发生了变化,新生成了build.xml及local.properties文件如下图。
已经生成的build.xml文件,是支持Ant全编译Android工程的,尝试着在命令行中输入ant debug即可打包生成APK。
ant debug
到了这一步即验证当前的开发环境是支持Ant脚本的。
接下来处理ANT脚本的改动。首先先编译local.properties。内容如下:
### 这个文件用来声明键对<key,value> ### 在build.xml中通过<property file="local.properties" />加载到ant中作为常量 sdk.dir=D:\\Mission\\adt-bundle-windows\\sdk ### 定义apk的包名 app_package=lab.sodino.testjni ### 定义apk的启动入口Activity app_launch_activity=lab.sodino.testjni.MainActivity
最后在build.xml中”<importfile=${sdk.dir}/tools/ant/build.xml”/>中增加如下Ant脚本内容:
<import file="${sdk.dir}/tools/ant/build.xml" /> <!-- ==================以下为新增加的内容================== --> <target name="easy"> <!-- 编译生成最新的so文件 --> <antcall target="ndk_build"/> <!-- 编译apk工程 --> <antcall target="debug"/> <!-- 执行安装 --> <antcall target="install" /> <!-- 启动主界面 --> <antcall target="startActivity" /> </target> <!-- target<description>可通过ant -p命令查看 --> <target name="ndk_build" description="Compile c/c++ code to so file."> <exec executable="ndk-build.cmd"/> <echo message="out.final.file----${out.final.file}"></echo> </target> <target name="install" description="install debug.apk"> <!-- target:debug调用过后,out.filal.file才会作为常量被初始化。所以单独调用install是无效的 --> <echo message="adb install -r ${out.absolute.dir}/${ant.project.name}-debug.apk"/> <apply executable="${sdk.dir}/platform-tools/adb.exe" failonerror="true"> <arg value=http://www.mamicode.com/"install" /> >代码具体含义可以看注释。
致此,修改TestJni.cpp代码后,只需在命令行下当前工程路径下输入
ant easy即可实现ndk-build+ 打包 + 安装 + 启动4个动作。如下图。
/**
* @author sodino
* @mail: sodino@qq.com
* 转载请保留出处。
*/[ANT] Ant脚本封装ndk-build命令并执行打包启动