android + JNI 调用动态库

今天开始写androidjni,其实这个部分应该昨天就开始的,但是昨天一天都纠结在环境的配置上面了,先讲一下昨天的内容吧,

昨天主要是配置环境:

我的系统:ubuntu12.04

android sdk 最新r20

android ndk 最新r8

eclipse juno mobile版本

jdk 1.7


昨天一开始的时候首先下载了myeclipse10.05,但是不知道是不是网络的原因(公司网络很卡)还是qiang的原因,一直都安装不了adt弄了半天都没有成功,只好放弃,删除后开始下载eclipsejuno版本。

原来下载的是classic版本,结果下载下来以后,在安装adt的步骤上面又卡住了,為什麼呢?原来现在下的adt版本是adt20,需要用到cdtndk用到)和swtadt用到)这两个包,昨天又不知道什么原因,利用eclipse竟然下不下来,我尝试了很多个下载地址可都失败了,个人猜测是下载地址又把中国的ip给封了,谁知道呢????后来仔细的查找了eclipse的各个版本,发现里面有个版本是给mobile开发准备的http://www.eclipse.org/downloads/packages/eclipse-mobile-developers/junor

仔细看了里面的组件,发现里面两个包都有,然后下载,安装adt无错通过。这个是feature列表


org.eclipse.cdt

 

org.eclipse.egit

 

org.eclipse.egit.import

 

org.eclipse.epp.package.common.feature

 

org.eclipse.equinox.p2.user.ui

 

org.eclipse.help

 

org.eclipse.jdt

 

org.eclipse.mylyn.context_feature

 

org.eclipse.mylyn.ide_feature

 

org.eclipse.mylyn.java_feature

 

org.eclipse.mylyn_feature

 

org.eclipse.platform

 

org.eclipse.rcp

 

org.eclipse.wst.xml_ui.feature

 

第一个和最后一个就是一开始提示出错的根源啊。


然后开始今天的步骤,

今天准备写jni动态库调用自己的静态库

步骤如下:

首先创建一个android工程,我的avd16也就是android4.1

然后在MainActivity里面写入:


packagecom.syd.twolib;


import android.os.Bundle;

import android.app.Activity;

import android.view.Menu;

import android.view.MenuItem;

import android.support.v4.app.NavUtils;


public class MainActivity extendsActivity {

static {

System.loadLibrary("JNITest");

}

privatenative String getReply();


@Override

public void onCreate(BundlesavedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}


@Override

public booleanonCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.activity_main, menu);

return true;

}


}


注意上面的加粗的语句,一个是我的包结构,一个是我添加的语句。


注意上面loadLibrary的名字实际上是JNITestSo这里需要将so除掉

接下来我按照网上的方法

进入工程路径

/workspace/Twolib$javah -classpath bin -d jni com.syd.twolib.MainActivity

Error: Could not find class file for'com.syd.twolib.MainActivity'.

结果报了个不能找到类的错,

然后又试了

~/workspace/Twolib$ javah -classpathbin/classes -d jni com.syd.twolib.MainActivity

Error: cannot accessandroid.app.Activity

class file for android.app.Activitynot found


发现又报了一个新的错误,只好又从网上查找资料,然后找到一个方法:

:~/workspace/Twolib$ javah -classpath/opt/android-sdk-linux/platforms/android-16/android.jar:bin/classes-d jni com.syd.twolib.MainActivity


发现这句语句的要点了吗??不错 就是classpath中加入了一个android.jar包,这个包的路径是androidsdk目录的platforms下面,看你自己的工程版本喽,一般都选择android-8版本,

执行语句,成功通过,


接下来在jni文件夹中创建一个c文件:com_syd_twolib_MainActivity.c:

#include <jni.h>

#define LOG_TAG "JNITest"

#include <utils/Log.h>


jint JNI_OnLoad(JavaVM* vm, void*reserved)

{

void *venv;

LOGI("JNI_OnLoad!");

if ((*vm)->GetEnv(vm,(void**)&venv, JNI_VERSION_1_4) != JNI_OK) {

LOGE("ERROR: GetEnvfailed");

return -1;

}

return JNI_VERSION_1_4;

}

/*

* Class: com_syd_twolib_MainActivity

* Method: getReply

* Signature: ()Ljava/lang/String;

*/

JNIEXPORT jstring JNICALLJava_com_syd_twolib_MainActivity_getReply(JNIEnv *, jobject)

{

LOGI("Hello world fromJNITest.so");

return(*env)->NewStrngUTF(env,"Hello World");

}

这里面要注意 JNI_OnLoadJNI_OnUnLoad这两个函数分别在加载和释放so的时候被调用。

但是这里為什麼会没有JNI_OnUnLoad呢?具体的原因我也不知道



/home/yxt/workspace/Twolib/jni/com_syd_twolib_MainActivity.c:19:error: conflicting types for 'JNI_OnUnload'

/opt/android-ndk-linux/platforms/android-14/arch-arm/usr/include/jni.h:1130:note: previous declaration of 'JNI_OnUnload' was here

这里提示说JNI_OnUnLoad已经有了 ,那我就删掉了这个函数


但是在编译的时候又遇到另外一个问题error:utils/Log.h: No such file or directory

意思是utils/Log.h无法找到,所以只好把log的那几句先给注释掉,这里再需要注意的是:注意代码中loadlibrary里面的名字必须和androidmk文件里面的名字一模一样,就算生成的。so文件里面加了前缀lib也不用去管他,于是再编译,通过!


先说解决方法:

JNIc文件中如果用到了#include<utils/Log.h>

然后用NDK编译的时候会提示error:utils/Log.h: No such file ordirectory

如果想要他的LOG功能的话

1-----
修改Android.mk文件配置,添加如下语句

LOCAL_LDLIBS+= -L$(SYSROOT)/usr/lib-llog

2-----
.c文件中修改为如下语句

#include<android/log.h>

3-----
使用方法

#defineLOG_TAG "debug"
#define LOGI(fmt, args...)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##args)
#defineLOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,fmt, ##args)
#define LOGE(fmt, args...)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, fmt,##args)


4----
打印语句

LOGI("testlog!!!!")

LOGI("the string is: %s\n",buff);


5----
错误输出到日志

LOGI(strerror(errno))

转自:http://blog.csdn.net/dspeeding/article/details/6924745

原因要追溯到jni的两种编译环境之间的区别:ndk和源码环境编译。

关于测试时使用Log。调用JNI进行NativeCode的开发有两种环境,完整源码环境以及NDK。两种环境对应的Log输出方式也并不相同,差异则主要体现在需要包含的头文件中。如果是在完整源码编译环境下,只要include<utils/Log.h>头文件(位于Android-src/system/core/include/cutils),就可以使用对应的LOGILOGD等方法了,当然LOG_TAGLOG_NDEBUG等宏值需要自定义。如果是在NDK环境下编译,则需要include<android/log.h>头文件(位于ndk/android-ndk-r4/platforms/android-8/arch-arm/usr/include/android/),另外自己定义宏映射,

来源:http://www.kunli.info/2011/08/21/android-native-code-study-note/




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: linux-android-韦根驱动 jni.rar 是一个文件名,其中包含了与韦根驱动相关的文件。 Linux是一种开源的操作系统,广泛应用于各种计算机设备。它具有优秀的稳定性、安全性和可定制性。Android是基于Linux内核开发的移动操作系统,目前在智能手机等智能设备上广泛使用。 韦根(Wiegand)驱动是一种用于读取磁卡、感应卡等卡片数据的驱动程序。它使用韦根协议来传输卡片的数据。韦根协议是一种串行通信协议,常用于门禁系统、考勤系统等场景中。这个驱动程序可以使得Linux系统和Android系统能够读取和处理韦根卡片的数据。 JNI(Java Native Interface)是一种Java编程语言的编程框架,用于在Java程序中调用其他语言(如C/C++)编写的本地代码。在这里,JNI用来链接Linux或Android系统的驱动程序和Java程序之间的接口。通过JNI,Java程序可以调用韦根驱动的功能,读取韦根卡片的数据并进行相应的处理。 而 ".rar" 则是一种常见的文件压缩格式,它可以将多个文件或文件夹压缩成一个单独的文件,以方便传输和存储。所以,"linux-android-韦根驱动 jni.rar" 这个文件可能是包含了与韦根驱动功能相关的Linux和Android系统驱动程序以及JNI接口的压缩文件。 ### 回答2: "linux-android-韦根驱动 jni.rar" 是一个压缩文件,包含了用于在 Linux 和 Android 系统上支持韦根驱动的 JNI(Java Native Interface)代码。 Linux 是一个开源的操作系统内核,Android 则是基于 Linux 内核开发的移动设备操作系统。韦根驱动是一种用于读取条码信息的通信协议,常用于条码扫描仪等设备。 这个压缩文件包含了 JNI 的相关代码,JNI 是 Java 提供的机制,用于在 Java 程序中调用本地(C/C++)代码。由于韦根驱动是由本地代码实现的,所以需要使用 JNI 将其与 Java 程序进行交互。 在 Linux 系统上,可以使用这个 JNI 文件来编译并生成与韦根驱动相关的动态链接库(.so 文件),以便在 Java 程序中调用。在 Android 系统上,可以将这个 JNI 文件与其它 Android 项目一起编译,并将生成的 .so 文件集成到 Android 应用中,以实现对韦根驱动的调用。 这个压缩文件的具体内容可能包括 JNI 源代码、头文件以及必要的编译脚本。如果你想使用这个韦根驱动,你可能需要先解压这个压缩文件,然后参考其中的文档或指南,按照指导进行相应的编译和集成工作。 总之,"linux-android-韦根驱动 jni.rar" 是一个提供了在 Linux 和 Android 系统上支持韦根驱动的 JNI 代码文件,通过使用它,你可以将韦根驱动融入到你的 Java 或 Android 项目中,并实现对该驱动的功能调用。 ### 回答3: Linux是一种开源的操作系统,广泛用于服务器、桌面电脑和嵌入式设备。而Android是基于Linux内核开发的移动操作系统,主要运行于智能手机、平板电脑和其他便携式设备上。韦根驱动是一种用于与韦根协议进行通信的驱动程序,通过JNI(Java Native Interface)将Java代码与本地代码进行交互。 在开发Android应用程序时,我们经常会使用JNI技术来调用C/C++编写的本地代码,以实现一些特定功能或与底层进行交互。在这个过程中,我们需要将本地代码打包成库文件,然后从Java层进行调用。 韦根驱动JNI.rar可能是一个包含了韦根协议通信所需的本地代码的压缩文件。其中可能包含了以C/C++语言编写的代码和一些与之相关的资源文件。通过解压缩这个文件,我们可以得到驱动程序所需的源代码和资源文件,从而进行进一步的开发和调试。 这个韦根驱动JNI.rar文件可能为开发者提供了一种在Android平台上与韦根协议设备进行通信的解决方案。通过将相关的代码集成到Android应用程序中,开发者可以实现与韦根协议设备之间的数据交互,从而实现特定的功能或满足特定的需求。 总之,Linux是操作系统,Android是基于Linux的移动操作系统,韦根驱动是用于与韦根协议进行通信的驱动程序,而韦根驱动JNI.rar可能是一个包含了韦根驱动的本地代码的压缩文件,用于在Android平台上实现与韦根协议设备的通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值