android 中 编写jni

本文介绍如何使用Android NDK进行开发,包括配置环境、创建JNI工程、编写C代码并调用等步骤,解决常见编译问题。
一、关于NDK:
NDK全称:Native Development Kit。 
1、NDK是一系列工具的集合。 
NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。 
NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。 
NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。 
2、NDK提供了一份稳定、功能有限的API头文件声明。 
Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog)。


二、NDK实例的实现:

对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK,所以为Eclipse需要配置的builder,其实是执行Cygwin,然后传递ndk-build作为参数。在NDKr7开始,Google的Windows版的NDK提供了一个ndk-build.cmd的脚本,这样,就可以直接利用这个脚本编译,而不需要使用Cygwin了。只需要为EclipseAndroid工程添加一个Builders,就能让Eclipse自动编译NDK。


本文是讲述NDK-r8下的实现实例。
下面是使用NDK-r8在windows下配置自动编译的builders的过程(实际上对于Linux,只需要修改ndk-build.cmd为ndk-build就可以了。)。
(1)先下载安装NDK-r8。
下载地址:http://developer.android.com/sdk/ndk/index.html,这个如果不好下载,请在网上找好下的地址:http://download.youkuaiyun.com/detail/kaitiren/4816723
下载后解压缩就可以用了。


准备好ndk后,具体创建jni 的工程


配置好Java环境变量;



 

然后控制台进入项目的bin/classes,输入javah -jni命令,生成相关.h头文件;



 如果报找不到Activity类的话可以暂时去掉MainActivity中的extends Activity声明,并把与Activity相关代码注释,再次编译后运行javah -jni,就没有错了,这时生成一个.h头文件,com_example_jnitest_MainActivity.h

在工程中创建jni目录,把头文件移动到里面,头文件里包含了以后要在.c文件中书写的函数:

C代码   收藏代码
  1. /* DO NOT EDIT THIS FILE - it is machine generated */  
  2. #include <jni.h>  
  3. /* Header for class com_example_jnitest_MainActivity */  
  4.   
  5. #ifndef _Included_com_example_jnitest_MainActivity  
  6. #define _Included_com_example_jnitest_MainActivity  
  7. #ifdef __cplusplus  
  8. extern "C" {  
  9. #endif  
  10. /* 
  11.  * Class:     com_example_jnitest_MainActivity 
  12.  * Method:    fun1 
  13.  * Signature: ()V 
  14.  */  
  15. JNIEXPORT void JNICALL Java_com_example_jnitest_MainActivity_fun1  
  16.   (JNIEnv *, jobject);  
  17.   
  18. /* 
  19.  * Class:     com_example_jnitest_MainActivity 
  20.  * Method:    fun2 
  21.  * Signature: ()Ljava/lang/String; 
  22.  */  
  23. JNIEXPORT jstring JNICALL Java_com_example_jnitest_MainActivity_fun2  
  24.   (JNIEnv *, jobject);  
  25.   
  26. /* 
  27.  * Class:     com_example_jnitest_MainActivity 
  28.  * Method:    fun3 
  29.  * Signature: ()C 
  30.  */  
  31. JNIEXPORT jchar JNICALL Java_com_example_jnitest_MainActivity_fun3  
  32.   (JNIEnv *, jobject);  
  33.   
  34. /* 
  35.  * Class:     com_example_jnitest_MainActivity 
  36.  * Method:    fun4 
  37.  * Signature: ()I 
  38.  */  
  39. JNIEXPORT jint JNICALL Java_com_example_jnitest_MainActivity_fun4  
  40.   (JNIEnv *, jobject);  
  41.   
  42. /* 
  43.  * Class:     com_example_jnitest_MainActivity 
  44.  * Method:    fun5 
  45.  * Signature: ()D 
  46.  */  
  47. JNIEXPORT jdouble JNICALL Java_com_example_jnitest_MainActivity_fun5  
  48.   (JNIEnv *, jobject);  
  49.   
  50. /* 
  51.  * Class:     com_example_jnitest_MainActivity 
  52.  * Method:    fun6 
  53.  * Signature: (ILjava/lang/String;)V 
  54.  */  
  55. JNIEXPORT void JNICALL Java_com_example_jnitest_MainActivity_fun6  
  56.   (JNIEnv *, jobject, jint, jstring);  
  57.   
  58. #ifdef __cplusplus  
  59. }  
  60. #endif  
  61. #endif  

 

与java原文件中相应的native函数都已经在这个头文件中声明好了,以后只要按相应的函数名书写函数,就可以在java原文件中调用。

写一个Android.mk文件,该文件说明了.c文件编译的相关信息:



 

Android.mk代码   收藏代码
  1. LOCAL_PATH := $(call my-dir)  
  2.   
  3. include $(CLEAR_VARS)  
  4.   
  5. LOCAL_MODULE    := myjni  
  6. LOCAL_SRC_FILES := main.c  
  7.   
  8. include $(BUILD_SHARED_LIBRARY)  

 其中指明了将main.c便以为myjni;

所以开始写一个main.c

 

C代码   收藏代码
  1. #include<jni.h>  
  2. #include<string.h>  
  3.   
  4. void JNICALL Java_com_example_jnitest_MainActivity_fun1  
  5.   (JNIEnv *, jobject);  
  6.   
  7. jstring Java_com_example_jnitest_MainActivity_fun2  
  8.   (JNIEnv *e, jobject o){  
  9.     return (*e)->NewStringUTF(e, "Thank Listron for using jni!");  
  10. }  
  11.   
  12. jchar Java_com_example_jnitest_MainActivity_fun3  
  13.   (JNIEnv *, jobject);  
  14.   
  15. jint Java_com_example_jnitest_MainActivity_fun4  
  16.   (JNIEnv *, jobject);  
  17.   
  18. jdouble Java_com_example_jnitest_MainActivity_fun5  
  19.   (JNIEnv *, jobject);  
  20.   
  21. void Java_com_example_jnitest_MainActivity_fun6  
  22.   (JNIEnv *, jobject, jint, jstring);  

 

至于语法可以参考其他资料

然后就要为项目添加C编译器来将C代码编译成so文件以便调用:

单击项目->属性:



 

 在builders选项卡中选new,添加一个Program编译器:



 编译器配置界面:



 Location是NDK解压目录下的ndk-build.cmd

WorkingDirectory选择当前项目空间,保存



 

这时编译器列表中多了一个编译器,将其通过Up移到最高处,以使C代码能在最先编译.


其的选项配置如下:
  【Edit Configuration】对话框中,配置选项卡【Refresh】。
      勾选“Refresh resources upon completion”,
      勾选“The entire workspace”,
      勾选“Recuresively include sub-folders”。
 
  【Edit Configuration】对话框中,配置选项卡【Build options】。
      勾选“After a “Clean””,
      勾选“During manual builds”,
      勾选“During auto builds”,
      勾选“Specify working set of relevant resources”。
 
      点击“Specify Resources…”
      勾选TestNdk工程的“jni“目录,点击”finish“。 
点击“OK“,完成配置。


但是到此我总是遇到如下的错误:

** No rule to make target `*', needed by `obj/local/armeabi/objs/*'.  Stop.

这是因为,在编写Android.mk时,里面有空格导致,重新删除里面的空格在尝试.


成功后:Console会显示:

Console代码   收藏代码
  1. "Compile thumb : myjni <= main.c  
  2.   
  3. SharedLibrary  : libmyjni.so  
  4.   
  5. Install        : libmyjni.so => libs/armeabi/libmyjni.so  

说明编译成功,项目中的lib多了.so文件:



 在java代码中通过以下声明调用该链接库:

Java代码   收藏代码
  1. static{  
  2.         System.loadLibrary("myjni");  
  3.     }  
 


参考的文档:http://blog.youkuaiyun.com/sky1203850702/article/details/41896689

http://hzy3774.iteye.com/blog/1706373


内容概要:本文详细介绍了一个基于Java和Vue的联邦学习隐私保护推荐系统的设计与实现。系统采用联邦学习架构,使用户数据在本地完成模型训练,仅上传加密后的模型参数或梯度,通过中心服务器进行联邦平均聚合,从而实现数据隐私保护与协同建模的双重目标。项目涵盖完整的系统架构设计,包括本地模型训练、中心参数聚合、安全通信、前后端解耦、推荐算法插件化等模块,并结合差分隐私与同态加密等技术强化安全性。同时,系统通过Vue前端实现用户行为采集与个性化推荐展示,Java后端支撑高并发服务与日志处理,形成“本地训练—参数上传—全局聚合—模型下发—个性化微调”的完整闭环。文中还提供了关键模块的代码示例,如特征提取、模型聚合、加密上传等,增强了项目的可实施性与工程参考价值。 适合人群:具备一定Java和Vue开发基础,熟悉Spring Boot、RESTful API、分布式系统或机器学习相关技术,从事推荐系统、隐私计算或全栈开发方向的研发人员。 使用场景及目标:①学习联邦学习在推荐系统中的工程落地方法;②掌握隐私保护机制(如加密传输、差分隐私)与模型聚合技术的集成;③构建高安全、可扩展的分布式推荐系统原型;④实现前后端协同的个性化推荐闭环系统。 阅读建议:建议结合代码示例深入理解联邦学习流程,重点关注本地训练与全局聚合的协同逻辑,同时可基于项目架构进行算法替换与功能扩展,适用于科研验证与工业级系统原型开发。
源码来自:https://pan.quark.cn/s/a4b39357ea24 遗传算法 - 简书 遗传算法的理论是根据达尔文进化论而设计出来的算法: 人类是朝着好的方向(最优解)进化,进化过程中,会自动选择优良基因,淘汰劣等基因。 遗传算法(英语:genetic algorithm (GA) )是计算数学中用于解决最佳化的搜索算法,是进化算法的一种。 进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择、杂交等。 搜索算法的共同特征为: 首先组成一组候选解 依据某些适应性条件测算这些候选解的适应度 根据适应度保留某些候选解,放弃其他候选解 对保留的候选解进行某些操作,生成新的候选解 遗传算法流程 遗传算法的一般步骤 my_fitness函数 评估每条染色体所对应个体的适应度 升序排列适应度评估值,选出 前 parent_number 个 个体作为 待选 parent 种群(适应度函数的值越小越好) 从 待选 parent 种群 中随机选择 2 个个体作为父方和母方。 抽取父母双方的染色体,进行交叉,产生 2 个子代。 (交叉概率) 对子代(parent + 生成的 child)的染色体进行变异。 (变异概率) 重复3,4,5步骤,直到新种群(parentnumber + childnumber)的产生。 循环以上步骤直至找到满意的解。 名词解释 交叉概率:两个个体进行交配的概率。 例如,交配概率为0.8,则80%的“夫妻”会生育后代。 变异概率:所有的基因中发生变异的占总体的比例。 GA函数 适应度函数 适应度函数由解决的问题决定。 举一个平方和的例子。 简单的平方和问题 求函数的最小值,其中每个变量的取值区间都是 [-1, ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值