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

在使用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++来开发应用)。希望这一天早些到来。

(0)

相关推荐

  • python生成器的使用方法

    什么是生成器?生成器是一个包含了特殊关键字yield的函数.当被调用的时候,生成器函数返回一个生成器.可以使用send,throw,close方法让生成器和外界交互. 生成器也是迭代器,但是它不仅仅是迭代器,拥有next方法并且行为和迭代器完全相同.所以生成器也可以用于python的循环中, 生成器如何使用? 首先看一个例子: 复制代码 代码如下: #!/usr/bin/python# -*- coding: utf-8 -*- def flatten(nested):    for subli

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

    在使用AndroidNDK开发的时候有个事情是很烦人的,那就是创建本地代码文件夹,生成本地代码文件和创建本地代码的编译文件.特别是实现本地方法的时候,也是比较烦人的,因为本地方法的名字实在是太长了.它的命名规范是:Java_package-name_class-name_method-name(arguments),稍一不留神就会有拼写错误,而导致长时间的调试.由于不勘忍受这样的折磨,也为了不重复同样的事情(DRY-Don't Repeat Yourself),于是就写了一个Java程序来做这件

  • Kotlin开发Android应用实例详解

    Kotlin开发Android应用实例详解 相关文章:关于Kotlin语言的基础介绍: http://www.jb51.net/article/114086.htm 我们简单的知道了Kotlin这门新语言的优势,也接触了一些常见的语法及其简单的使用,相信你会对它有浓厚的兴趣,暂且理解为对它感兴趣吧,哈哈哈.那么,我们该如何在Android中应用这门新的语言呢?今天的这篇文章带你学习使用Kotlin开发Android应用,并对比我们传统语言Java,让你真真切切的感受到他的美和优雅. 配置 项目g

  • Android Socket通信详解

    一.Socket通信简介  Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是"请求-响应方式",即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据.而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求. 那么,什么是socket?Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信.通过

  • Python高级特性之切片迭代列表生成式及生成器详解

    目录 切片 迭代 列表生成式 生成器 迭代器 在Python中,代码越少越好.越简单越好.基于这一思想,需要掌握Python中非常有用的高级特性,1行代码能实现的功能,决不写5行代码.代码越少,开发效率越高. 切片 tuple,list,字符串都可以进行切片操作 L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack'] L[0:3] # ['Michael', 'Sarah', 'Tracy'] L[:3] # ['Michael', 'Sarah', '

  • 基于hashlib模块--加密(详解)

    用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法 import hashlib m = hashlib.md5() m.update(b"hello") print(m.hexdigest()) m.update(b"It's me") print(m.hexdigest()) m.update(b"It's been a long time sin

  • 基于js 本地存储(详解)

    在客户端运行的JS是不能操作用户电脑磁盘中的文件的(保护客户端运行的安全) 1.JS中的本地存储: 使用JS向浏览器的某一个位置中存储一些内容,浏览器即使关闭了,存储的信息也不会销毁,当在重新打开浏览器的时候我们依然可以获取到上一次存储的信息 本地存储的方案: 传统: cookie:把信息存储到客户端的浏览器中(但是项目服务器端也是可以获取COOKIE的) session:把信息存储到服务器上的(服务器存储) HTML5:webStorage localStorage:永久存储在客户端的本地 s

  • 基于php编程规范(详解)

    今天写这个是为了 提醒自己 编程过程 不仅要有逻辑 思想 还有要规范 代码 这样可读性 1.PHP 编程规范与编码习惯最主要的有以下几点: 1 文件说明 2 function 函数体说明 3 代码缩进 4 if省略 5 变量规范 6 命名规范 7 十行一注释 8 注释风格 9 开放关闭原则 2.文件说明 个人代码 -规范如下: <? /* +---------------------------------------------------------------------- + Title

  • 基于python爬虫数据处理(详解)

    一.首先理解下面几个函数 设置变量 length()函数 char_length() replace() 函数 max() 函数 1.1.设置变量 set @变量名=值 set @address='中国-山东省-聊城市-莘县'; select @address 1.2 .length()函数 char_length()函数区别 select length('a') ,char_length('a') ,length('中') ,char_length('中') 1.3. replace() 函数

  • Android 文件操作详解及简单实例

     Android 文件操作详解 Android 的文件操作说白了就是Java的文件操作的处理.所以如果对Java的io文件操作比较熟悉的话,android的文件操作就是小菜一碟了.好了,话不多说,开始今天的正题吧. 先从一个小项目入门吧 首先是一个布局文件,这一点比较的简单,那就直接上代码吧. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="htt

  • Android中SharedPreference详解及简单实例

     Android中SharedPreference详解 SharedPreference是Android提供的一种轻量级的数据存储方式,主要用来存储一些简单的配置信息,例如,默认欢迎语,登录用户名和密码等.其以键值对的方式存储,使得我们能很方便进行读取和存入. SharedPreference 文件保存在/data/data/<package name>/shared_prefs 路径下(如/data/data/com.android.alarmclock/shared_prefs/com.a

随机推荐