基于Android本地代码生成器详解
发布时间:2022-09-15 02:52:26
在使用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++来开发应用)。希望这一天早些到来。


猜你喜欢
- 正常状态是UP,跳闸是⼀种状态CIRCUIT_OPEN,可以通过/health查看,前提是工程中需要引入SpringBoot的actuato
- 一、int还记得 C 语言里的 int 吗,C里面的 int 有着无符号与有符号之分但是Java内就没有,且固定占4个字节大小,也就是32比
- 本文实例为大家分享了java实现双色球机选 * 的具体代码,供大家参考,具体内容如下双色球号码1~32不重复选6个(排序好),1~16中
- 前言说实话当第一次看到这个需求的时候,第一反应就是Canvas只有drawLine方法,并没有drawDashLine方法啊!这咋整啊,难道
- 如何解决yml没有spring小叶子标志我的idea springboot项目中有两个.yml文件,一个application.yml,一个
- 优麒麟Ubuntu20.04中使用VS Code。VS Code的版本是1.48.0。以下内容仅限于上述环境,对于Windows环境下的使用
- 提起ProgressBar,想必大家都比较熟悉,使用起来也是比较方便,直接在XML文件中引用,然后添加属性,运行就OK了,虽然使用Progr
- 本文实例为大家分享了Java实现窗体程序显示日历的具体代码,供大家参考,具体内容如下实训要求:1.使用BorderLayout 进行总体布局
- 项目中有几个batch需要检查所有的用户参与的活动的状态,以前是使用分页,一页一页的查出来到内存再处理,但是随着数据量的增加,效率越来越低。
- 本文实例为大家分享了C#实现简单点餐系统的具体代码,供大家参考,具体内容如下实现简单点餐系统剖析1、设计界面(给菜品的序号(index),名
- 引用Spring官方文档的说法介绍一下@Conditional注解:Spring5.0.15版本@Conditional注解官方文档@Con
- Java 判断字符串是否为IP地址,供大家参考,具体内容如下1、代码主要就是这么几个条件非空长度符合 0.0.0.0 - 255.255.2
- 将10个整数按由小到大的顺序排列#include <iostream>using namespace std;int main(
- 本文实例讲述了android编程之ip2id程序。分享给大家供大家参考。具体分析如下:一、说明:公司一个项目中需要给一系列网络设备分配id号
- 1.首先,八种基本数据类型分别是:int、short、float、double、long、boolean、byte、char; &
- 一、JPA介绍JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系
- 目录一.什么是负载均衡二.负载均衡的简单分类三.为什么需要做负载均衡四.springCloud如何开启负载均衡五.IRule1.Random
- 两个对象进行比较相等,有两种做法:1、情况一:当仅仅只是判断两个对象是否相等时,只需重写equals()方法即可。这里就不用说明2、情况二:
- 摘要: 前面介绍了MapStrut简单用法,MapStrut的最重要的特点就是处理Java中实体与模型间不匹配属性的转换。实体模型有一个Us
- 最近项目中有截屏的需求,普通的view截屏方法网上一搜一大把,但是SurfaceView截屏黑屏问题很多文章说的并不清楚,自己参考了一些别的