开发环境:windows2007, eclipse

做anroid越深发现用到底层开发的时候越多,但是我以前也没有搞过,因此现在打算好好学习学习。先从最简单的做起。正所谓万事开头难啊。

搞了近一天终于把在windows下,用eclipse开发Android JNI给倒腾通了。下面将详细讲解其操作步骤和我在其中遇到的问题

参考:http://www.cnblogs.com/bastard/archive/2012/05/19/2508913.html

http://blog.csdn.net/cghs123/article/details/7044826

1.新建Android工程 JNITest

在HelloWorld的Activity中添加加载c库的代码,系统运行后自动执行该段

    static
{
//加载库文件
System.loadLibrary("HelloWorldJni");
}

声明c库中需要自定义的原生函数

    private native String printJNI(String inputStr);

HelloWorld整段代码如下:

 package com.sirc.jni;

 import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu; public class HelloWorld extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); String jniStr=printJNI("I am HelloWorld Activity");
Log.v("android", jniStr); }
static
{
//加载库文件
System.loadLibrary("HelloWorldJni");
}
//声明原生函数 参数为String类型 返回类型为String
private native String printJNI(String inputStr); @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }

2.生成共享库的头文件

详细步骤见上一文章《Android JNI开发生成.h头文件问题》http://www.cnblogs.com/gisdream/p/3521090.html

我们都知道在Eclipse中新建类后,eclipse会帮助我们在项目下自动建立去对应的class文件,位于项目目录下的\bin\classes中。共享库的头文件可以根据class文件通过javah编译生成。

通过命令进入项目根目录

再输入命令:javah -classpath bin\classes -d jni com.sirc.jni.HelloWorld

可以得到头文件com_sirc_jni_HelloWorld.h,位于跟目录/jni/下面

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_sirc_jni_HelloWorld */ #ifndef _Included_com_sirc_jni_HelloWorld
#define _Included_com_sirc_jni_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_sirc_jni_HelloWorld
* Method: printJNI
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_sirc_jni_HelloWorld_printJNI
(JNIEnv *, jobject, jstring); #ifdef __cplusplus
}
#endif
#endif

头文件中定义了与上层的访问接口Java_com_sirc_jni_HelloWorld_printJNI,方法名是按照”Java_包名_类名_方法名“来命名的。

3.实现JNI原生函数源文件

在jni文件夹下面新建com_sirc_jni_HelloWorld.c文件,文件代码如下:

#include <jni.h>
#define LOG_TAG "HelloWorld"
#include <android/log.h> #define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##args)
#define LOGD(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)
/* Native interface, it will be call in java code */
JNIEXPORT jstring JNICALL Java_com_sirc_jni_HelloWorld_printJNI(JNIEnv *env,
jobject obj, jstring inputStr) {
LOGI("dufresne Hello World From libhelloworld.so!");
// 从 instring 字符串取得指向字符串 UTF 编码的指针
const char *str = (const char *) (*env)->GetStringUTFChars(env, inputStr,
JNI_FALSE);
LOGI("dufresne--->%s", (const char *)str);
// 通知虚拟机本地代码不再需要通过 str 访问 Java 字符串。
(*env)->ReleaseStringUTFChars(env, inputStr, (const char *) str);
return (*env)->NewStringUTF(env, "Hello World! I am Native interface");
} /* This function will be call when the library first be load.
* You can do some init in the libray. return which version jni it support.
*/
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
void *venv;
LOGI("dufresne----->JNI_OnLoad!");
if ((*vm)->GetEnv(vm, (void**) &venv, JNI_VERSION_1_4) != JNI_OK) {
LOGE("dufresne--->ERROR: GetEnv failed");
return -1;
}
return JNI_VERSION_1_4;
}

其中#include <android/log.h>应用了打印日志头文件,并声明了集中打印方法,包括info,debug,error。我想这应该是调用的android的内部系统文件,在这里对其进行了一个重声明

#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##args)
#define LOGD(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)

JNI_OnLoad函数JNI规范定义的,当共享库第一次被加载的时候会被回调。

Java_com_sirc_jni_HelloWorld_printJNI是头文件中方法的实现,可以通过这里获取上层传过来的参数,并在这里返回数据给上层框架使用。

注:这段代码是从其他网站上copy过来的,运行时如果出现错误stray '/241' in program ,该错误是指源程序中有非法字符,需要去掉非法字符。

解决方法:来源于http://blog.sina.com.cn/s/blog_6bc5571a0100zmft.html

(1)把所粘的文字放到记事本里就行了

(2)把出错行的空格删掉重新打一下试试。

4.编译生成so库

4.1在jni文件夹下面新建Android.mk文件,文件内容如下:

LOCAL_PATH:= $(call my-dir)
# 一个完整模块编译
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=com_sirc_jni_HelloWorld.c
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_MODULE := libHelloWorldJni
LOCAL_SHARED_LIBRARIES := libutils
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_TAGS :=optional
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)

系统变量解析:

  LOCAL_PATH - 编译时的目录
  $(call 目录,目录….) 目录引入操作符
    如该目录下有个文件夹名称 src,则可以这样写 $(call src),那么就会得到 src 目录的完整路径

  include $(CLEAR_VARS) -清除之前的一些系统变量
  LOCAL_MODULE - 编译生成的目标对象
  LOCAL_SRC_FILES - 编译的源文件
  LOCAL_C_INCLUDES - 需要包含的头文件目录
  LOCAL_SHARED_LIBRARIES - 链接时需要的外部库
  LOCAL_PRELINK_MODULE - 是否需要prelink处理 
  include$(BUILD_SHARED_LIBRARY) - 指明要编译成动态库

  android.mk编译模块添加具体方法参考:http://blog.csdn.net/yili_xie/article/details/4906865

4.2编译

我这里使用NDK来进行编译,首先要下载安装NDK。

Android NDK安装很简单,直接到http://developer.android.com/tools/sdk/ndk/index.html 下载android-ndk-r8e-windows-x86.zip 解压即可,接着设置环境变量。右击我的电脑属性,切换到高级选项卡,单击环境变量,在系统变量下单击编辑在Path变量名下直接变量值;D:\Android\android-ndk-r8e-windows-x86\android-ndk-r8e\ ,也就是你的解压路径,其中有个封号与前面的变量值分割。单击确定NDK就安装好了。

在命令行中使用ndk-build编译,过程如下

编译成功后会自动生成libs/armeabi/libHelloWorldJni.so文件。

5.运行测试

运行JNITest项目,在logcat中查看运行结果。可以看到

上层打印情况:

底层打印情况:

以上便是一个完整的开发JNI的实例,下一篇将详细研究参数传值,java中基本类型和c++基本类型的关联。

andorid jni入门教程一之helloworld的更多相关文章

  1. (转)JNI入门教程之HelloWorld篇 .

    转: http://blog.csdn.net/mingjava/article/details/180946 本文讲述如何使用JNI技术实现HelloWorld,目的是让读者熟悉JNI的机制并编写第 ...

  2. 无废话SharePoint入门教程一[SharePoint概述]

    一.前言 听说SharePoint也有一段时间了,可一直处在门外.最近被调到SharePoint实施项目小组,就随着工作一起学习了一下实施与开发.但苦于网上SharePoint入门的东西实在太少,导致 ...

  3. 【Cocos2d入门教程一】Cocos2d-x环境搭建

    在进行Cocos2d游戏开发前 我们先来配置一下环境,我们先来准备一下工具,我们所需要的工具分别为: 1.Cocos2d引擎 2.JDK 3.SDK 4.NDK 5.ANT 6.ADT 1.下载Coc ...

  4. [转]无废话SharePoint入门教程一[SharePoint概述]

    本文转自:http://www.cnblogs.com/iamlilinfeng/p/3026332.html 一.前言 听说SharePoint也有一段时间了,可一直处在门外.最近被调到ShareP ...

  5. typescript 入门教程一

    ##### 从今天开始,持续更新typescript入门教程系列.... 目前ts越来越火,主流的前端框架,好比*angular,vue 3*均是采用ts来编写,所有很多公司的项目都是用**ts**来 ...

  6. Zephir入门教程一

    一.如何安装 zephir-安装和初体验:http://blog.csdn.net/u011142688/article/details/51619811 二.如何使用 需要切到工作目录下,也就是co ...

  7. Angular入门教程一

    1 前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,紧跟时代潮流,学习掌握新知识自然是不敢怠慢. AngularJS是google在维护,其在国外已经十分火热,可是国内的 ...

  8. Gemini.Workflow 双子工作流入门教程一:定义流程:流程图属性

    简介: Gemini.Workflow 双子工作流,是一套功能强大,使用简单的工作流,简称双子流,目前配套集成在Aries框架中. 下面介绍本篇教程:流程定义:流程图属性. 步骤一:在流程管理的流程定 ...

  9. Unity -- 入门教程一

    首先声明一下,我用的Unity版本是4.6.6,编译环境是VS2010,其余的我会慢慢介绍,安装的过程这里我就不做讲解了,度娘那会做的比我详细.安装包可以在最下面的联系方式找我要,现在开始进入主题.  ...

随机推荐

  1. Django项目深入理解

    python应用松耦合比方说,考虑有一个以前写的视图函数,这个函数显示当前日期和时间.如果我们想把它的URL 从原来的 /time/ 改变到/currenttime/ ,我们只需要快速的修改一下URL ...

  2. 详解Bootstrap表单组件

    表单常见的元素主要包括:文本输入框.下拉选择框.单选框.复选框.文本域.按钮等.下面是不同的bootstrap版本: LESS:  forms.less SASS:  _forms.scss boot ...

  3. 用非管理员权限启动主程序,并用管理员权限启动子程序,导致WM_COPYDATA消息发送失败的问题

    问题描述 :     用非管理员权限启动dzh,dzh再启动dtssm,由于dtssm的配置文件app.manifest 中设置了requireAdministrator,导致dtssm总是以管理员权 ...

  4. Win7下VS2010使用“ASP.Net 3.5 Claims-aware Template”创建ClaimsAwareWebSite报"HRESULT: 0x80041FEB"错误的解决办法

    问题描述: 使用VS2010的WIF开发模板创建“Claims-aware ASP.NET Site”.“Claims-aware WCF Service”,下载安装后,创建网站时,报错"H ...

  5. css3动画特效:纯css3制作win8加载动画特效

    Windows 8     完整效果如上图:这个里面可能是css冲突,喜欢的可以自己去体征一下:   css特效代码: <style type="text/css"> ...

  6. oreData的学习记录

    1.如果想创建一个带有coreData的程序,要在项目初始化的时候勾选中 2.创建完成之后,会发现在AppDelegate里多出了几个属性,和2个方法 <span style="fon ...

  7. blueImp/jQuery file upload 的正确用法(限制上传大小和文件类型)

    这个插件太出名了,几乎能完成所有能想象的到的效果,包括进度条.拖拽.甚至现在已经完美支持图片视频等的处理,三个字形容就是屌爆了.最近在做上传这一部分,发现网上对于上传文件大小的限制和类型检测等的方法都 ...

  8. ubuntu下安装多版本Python

    今天一不小心又把ubuntu系统给完坏了,因为我把python3卸载了,然后就...好了,不废话了,接下来就说一下如何在ubuntu下管理python的多个版本.我这里使用的是一个叫pyenv的Pyt ...

  9. 2.C#中通过委托Func消除重复代码

    阅读目录   一:重复的代码 二:C#中通过委托Func消除重复代码 一:重复代码    public class Persion { public string Name { get; set; } ...

  10. Java程序员转Android开发必读经验分享

    小编最近几日偷偷的发现部分Java程序员想转安卓开发,故此加紧补充知识,为大家搜集资料,积极整理前人的经验,希望可以给正处于困惑中的你,带来些许的帮助. 啰哩啰嗦的说说Java和Android程序的区 ...