首页 > 代码库 > [ANT] Ant脚本封装ndk-build命令并执行打包启动

[ANT] Ant脚本封装ndk-build命令并执行打包启动


本篇文章为示范如何在Eclipse中开始一个Jni工程的操作步骤,并假设读者初步了解JNI具体规范及使用ANT脚本。(话说这样的初学者不多见吧…其实我只是想给自己写个总结而已)

/**                                          
 * @author sodino             
 * @mail: sodino@qq.com
 * 转载请保留出处。         
 */                                     

阅读本文之前,请确保你的开发环境已经满足如下配置:

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命令并执行打包启动