欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

基于Android本地代码生成器详解

程序员文章站 2023-11-20 17:31:40
在使用androidndk开发的时候有个事情是很烦人的,那就是创建本地代码文件夹,生成本地代码文件和创建本地代码的编译文件。特别是实现本地方法的时候,也是比较烦人的,因为本...
在使用androidndk开发的时候有个事情是很烦人的,那就是创建本地代码文件夹,生成本地代码文件和创建本地代码的编译文件。特别是实现本地方法的时候,也是比较烦人的,因为本地方法的名字实在是太长了。它的命名规范是:java_package-name_class-name_method-name(arguments),稍一不留神就会有拼写错误,而导致长时间的调试。由于不勘忍受这样的折磨,也为了不重复同样的事情(dry-don't repeat yourself),于是就写了一个java程序来做这件事。
这个小工具可以逐个检查java文件,并创建含有本地方法文件,也即本地代码文件,生成android.mk编译文件并更新java文件,添加system.loadlibrary。
具体的原则是这样:
•每个含有本地代码的java文件,生成一个本地文件,其内含有该文件中的所有本地方法
•所生成的本地方法是符合标准的jni,具体的形式是:
复制代码 代码如下:

return-type java_package-name_class-name_method-name(arguments){
       }

也就是说,所需要做的只是实现这个方法。
•默认本地代码共享库的名字是android项目的名字
有了这个小工具,就可以只在java中声明本地方法,运行下这个工具,然后实现本地方法,再编译就可以了。
可以从<>这个小工具。解压后有三个文件一个是java源码,一个是jar包(genjni.jar),一个是shell脚本(genjni.sh)。放上源码的原因是,如果有兴趣的朋友可以进行改进,但是改进后请
发我一份。下载后,最好修改下shell脚本,把jar文件的路径改成具体的存放路径,否则会报出找不到jar文件的错误。最后把genjni.sh放到~/bin下面,为了使用时方便。使用的时候要在android项目的根目录下面运行genjni.sh就可以了。
下面以一个实例方式演示下这个小工具的使用方法:
创建一个项目叫hellojni,并创建一个hellojniactivity,在其内声明一个本地方法getstringfromjni();并用有一个textview用来显示getstringfromjni()返回的信息。另一个本地方法getstatusfromjni(int)是为了显示用的,没有使用。这是java代码:
复制代码 代码如下:

package com.hilton.hellojni;
import android.app.activity;
import android.os.bundle;
import android.widget.textview;
public class hellojniactivity extends activity {
    /** called when the activity is first created. */
    @override
    public void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        setcontentview(r.layout.main);
        textview text = (textview) findviewbyid(r.id.text);
        text.settext(getstringfromjni());
    }

    private native string getstringfromjni();
    private native int getstatusfromjni(int type);
}

写好java代码后,从终端进入到项目的根目录下
复制代码 代码如下:

$cd hellojni
$ls
androidmanifest.xml  assets  bin  default.properties  gen  proguard.cfg  res  src
$genjni.sh
appplication hellojni
package name: com.hilton.hellojni
class name: hellojniactivity
$ls
androidmanifest.xml  assets  bin  default.properties  gen  jni  proguard.cfg  res  src
$ls jni
android.mk  hellojniactivity.c

打开查看android.mk和hellojniactivity.c
复制代码 代码如下:

local_path := $(call my-dir)
include $(clear_vars)
local_module    := hellojni
local_src_files := hellojniactivity.c
include $(build_shared_library)

复制代码 代码如下:

#include <jni.h>
jstring java_com_hilton_hellojni_hellojniactivity_getstringfromjni(jnienv* env, jobject thiz) {
}
jint java_com_hilton_hellojni_hellojniactivity_getstatusfromjni(jnienv* env, jobject thiz, jint type) {
}

再查看hellojniactivity.java也被更新了,里面多了加载共享库的语句:
复制代码 代码如下:

package com.hilton.hellojni;
import android.app.activity;
import android.os.bundle;
import android.widget.textview;
public class hellojniactivity extends activity {
    static {
        system.loadlibrary("hellojni");
    }
    /** called when the activity is first created. */
    @override
    public void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        setcontentview(r.layout.main);
        textview text = (textview) findviewbyid(r.id.text);
        text.settext(getstringfromjni());
    }

    private native string getstringfromjni();
    private native int getstatusfromjni(int type);
}

剩下的工作就是实现本地方法了。
当然这个工具还是有很多问题,欢迎各位反馈,或给出改进意见。
另外,这个工具是用java写的,更好的选择应该是用脚本来写,如perl或python。还有就是,如果能把这个工具集成到adt中,或是创造一个完全用于ndk开发的集成工具andt,能够像产生r.java那样的自动生成本地文件。比如做一个andt工具,集成到eclipse中,能够自动当java中有本地方法声明后就自动生成本地文件和编译文件。这将是多么美好的事情啊,将对ndk的开发有重大的帮助。我想,google应该会做一专门用于ndk开发的eclipse插件,或是在adt中加入对ndk的支持,因为ndk开放的接口越来越多,使用ndk开发者也将越来越多,基于ndk开发的应用也将越来越多(2.3及以后的版本,完全可以只用ndk开发出一个apk,也就是说用纯c/c++来开发应用)。希望这一天早些到来。