使用jni接口完成android本地程序的运行

简介:
最近在开发android相关的程序。可惜啊,android的开发接口都是基于java的,作为一个c开发者,于是我想开发一个c程序,然后想法root掉那个手机,然后使用adb工具将程序拷贝到手机里就可以运行了...想法很好,但是有两个问题,第一,靠点击根本无法运行本地程序;第二,如果程序发布,难道能指望用户将手机寄过来然后帮他们root吗?于是这个方法直接pass掉了。
     接下来,想把程序打包到一个基于java的apk中,安装的时候直接将程序复制到和apk相同的目录下,然后由java程序使用exec调用这个本地程序。实验证明,由于权限问题,不可行!后来又想将程序通过apk直接复制到SD卡上,但是通过查看android的源代码发现,SD卡被mount的时候是指定了noexec标志的,也就是说SD卡上的程序无法执行(这是有道理的,因为如果sd卡的程序可以执行的话,随便一个溢出漏洞就可能危害系统...再说,sd卡耗电,又不稳定)...于是,没有办法了!难道在android上开发程序必须用java吗?其实不是这样的!虽然接口是java,但是java明确规定了又jni接口可以调用本地程序的,如此看来,既然java对于android是被信任的,那么使用java的jni调用的本地程序也是被信任的(虽然java虚拟机并不管理它,但是它确实没有任何管理者监管啊),于是就想办法将要执行的本地程序封装成一个so(动态库),然后用java的loadlibrary执行之。
     以ABC c语言编写的程序为例,下面的步骤搞定了它,这里仅仅用java SE作为例子,没有使用android的sdk/ndk,然而其工作原理是一样:
1.首先写一个java程序,很简单的:Test.java
class Test 
{
    public native void jni_main();
    static {
        System.loadLibrary("abc");
    }
    public static void main(String[] args) {
        new Test().jni_main();
    }
}
2.生成头文件:
javah Test
生成Test.h
3.将Test.h复制到ABC的源码目录下
4.想办法将abc编译成libabcd.so(其实ABC本来在linux平台被编译成一个elf可执行文件的,这里要把它编译成so,用于java程序的jni接口加载)
4.1.修改abc.c,如下:
//int main(int argc, char* argv[]) {    //原来的main函数
JNIEXPORT void JNICALL Java_TestABC_Wrapper_1main (JNIEnv *env, jobject obj) {  //修改后的jni接口调用的main函数
...
}
4.2.编写Makefile文件:
#开始
CC      := droid-gcc
LD      := droid-ld
DEFS = ...#复制原来的Makefile的该字段
LIBS = ...#复制原来的Makefile的该字段
CFLAGS  := ...(复制原来Makefile的该CFLAGS) -I...#复制和android相关的头文件的路径
LDFLAGS := -shared -fpic
SOURCE  := $(wildcard *.c)
OBJS    := $(patsubst %.c,%.o,$(SOURCE))
TARGET_LIB := libabc.so
all:$(OBJS)
    $(LD) $(LDFLAGS) -o $(TARGET_LIB) $(OBJS) $(LIBS)
%.o:%.c
    $(CC) -c $(CFLAGS)  $< -o $*.o
 *.o -rf
#结束
5.编译,执行make,最终生成一个so,然后运行java Test,结果是abc被运行啦!

PS:我认为,google的android仅仅用java作为其主流开发语言,这是不妥的,这样就使得很多厂商望而却步,很多做c的人望而却步,本来android的用户就没有symbian的多,现在由于这个原因,更使得它只能在众多hacker圈子里打转,一般的手机用户是不懂什么linux的,也不关心什么root权限,因此很多hacker方略对于一般的用户是没有意义的,他们关心的最终的体验,因此很多的任务不得不压在开发者身上,开发者越多就意味着潜在用户越多,symbian走的就是这条路线,palm当初也许就是因为没有走这个路线而失败的。因此,不管怎么多,平台提供者不应该限制开发者,开放的越多,应用就会越多,众口难调的用户才会易于伺候。


 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1271175


相关文章
|
3月前
|
算法 数据处理 Android开发
掌握安卓性能优化的秘诀:电池寿命与运行效率的提升
【10月更文挑战第6天】 本文深入探讨了安卓应用开发中的性能优化技巧,重点分析了影响电池寿命和运行效率的关键因素,并提供了针对性的优化策略。通过代码优化、资源管理、后台任务处理等方法,开发者可以显著提升应用的续航能力和流畅度。同时,结合具体案例,展示了如何在实际开发中应用这些技巧,确保应用在各种场景下都能保持高效运行。本文旨在为安卓开发者提供实用的性能优化指导,助力其打造更优质的应用体验。
91 2
|
5月前
|
Java Android开发 C++
Android Studio JNI 使用模板:c/cpp源文件的集成编译,快速上手
本文提供了一个Android Studio中JNI使用的模板,包括创建C/C++源文件、编辑CMakeLists.txt、编写JNI接口代码、配置build.gradle以及编译生成.so库的详细步骤,以帮助开发者快速上手Android平台的JNI开发和编译过程。
424 1
|
7月前
|
Java API 开发工具
如何将python应用编译到android运行
【6月更文挑战第27天】本文介绍在Ubuntu 20上搭建Android开发环境,包括安装JRE/JDK,设置环境变量,添加i386架构,安装依赖和编译工具。并通过`p4a`命令行工具进行apk构建和清理。
154 6
如何将python应用编译到android运行
|
3月前
|
Java Unix Linux
Android Studio中Terminal运行./gradlew clean build提示错误信息
遇到 `./gradlew clean build`命令执行出错时,首先应检查错误信息的具体内容,这通常会指向问题的根源。从权限、环境配置、依赖下载、版本兼容性到项目配置本身,逐一排查并应用相应的解决措施。记住,保持耐心,逐步解决问题,往往复杂问题都是由简单原因引起的。
461 2
|
5月前
|
开发工具 Android开发
解决Android运行出现NDK at /Library/Android/sdk/ndk-bundle did not have a source.properties file
解决Android运行出现NDK at /Library/Android/sdk/ndk-bundle did not have a source.properties file
222 4
解决Android运行出现NDK at /Library/Android/sdk/ndk-bundle did not have a source.properties file
|
5月前
|
Android开发 iOS开发
[ionic]解决运行Android、IOS出现Could not find the web assets directory
[ionic]解决运行Android、IOS出现Could not find the web assets directory
49 1
|
5月前
|
Android开发 开发者
Android项目架构设计问题之使用动态代理来增强 GoodsApi 接口的调用如何解决
Android项目架构设计问题之使用动态代理来增强 GoodsApi 接口的调用如何解决
30 0
|
5月前
|
存储 缓存 Java
Android项目架构设计问题之优化业务接口数据的加载效率如何解决
Android项目架构设计问题之优化业务接口数据的加载效率如何解决
64 0
|
7月前
|
前端开发 JavaScript 测试技术
|
6月前
|
Oracle Java 关系型数据库
Android studio 安装以及第一个程序
Android studio 安装以及第一个程序
166 0

热门文章

最新文章