Android(java)学习笔记257:JNI之helloword案例(利用NDK工具)
1. 逻辑思路过程图:
2.下面通过一个HelloWorld案例来说明一下JNI利用NDK开发过程(步骤)
分析:我们在Win7系统下编译的C语言代码,我们知道C语言依赖操作系统,不能跨平台,所以我们要通过NDK工具把在Win7系统下编写的C代码,转化为可以在Linux(Linux2.6.6---Android内核)运行的二进制代码,最后通过JNI协议规范,Android中java代码就可以调用这个转化后的二进制代码运行。
(1)在Eclipse中新建一个Android工程,命名为"HelloWorld",如下:
接下来来到Android工程布局文件activity_main.xml,如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.himi.helloworld.MainActivity" > <Button
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="问C要Hello"
android:onClick="getHello"/> </RelativeLayout>
布局效果如下:
(2)来到Android工程的MainActivity.java,如下:
在Java中声明native方法
package com.himi.helloworld; import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast; public class MainActivity extends Activity { //通过JNI,调用C/C++代码,在C中实现的 (不是在Java层实现的)
public native String getHelloFromC();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} /**
* 按钮点击事件,获取C的hello问候
* @param view
*/
public void getHello(View view) {
Toast.makeText(this, "C代码问候:"+getHelloFromC(), 0).show();
} }
就这样一个Android工程的就搭建好了,接下来关于C代码:
(3)接下来在"HelloWorld"工程目录下,新建一个文件夹命名为" jni ",如下:
(4)在刚刚新建的" jni "文件夹下,我们新建一个hello.c文件,同时我们拷贝 jni.h 文件到 jni文件下,如下:
• hello.c :
#include <jni.h> char* getHello()
{
////////
return "hello Android From C";
} //jni协议给java调用
// 返回类型 方法名(Java_包名(使用"_"把包名分割)_类名_方法名 (参数) //JNIEnv* env jni的结构体数据,jni系统实现 ; obj java对象 调用该jni方法的对象
jstring Java_com_himi_helloworld_MainActivity_getHelloFromC(JNIEnv* env, jobject obj)
{
char* res = getHello();//获取到C代码字符串结果
/**
* (**env).GetVersion(env);
* (*env)->GetVerison(env);
*/
//jstring (*NewStringUTF)(JNIEnv*, const chat*);
jstring jres = (**env).NewStringUTF(env,res); return jres;
}
代码中,上面的getHello()是C语言代码;
下面的定义的 Java_com_himi_helloworld_MainActivity_getHelloFromC()方法是JNI协议的规范,这样写java才能调用getHello()方法,Java_com_himi_helloworld_MainActivity_getHelloFromC()起到过渡作用。
Java_com_himi_helloworld_MainActivity_getHelloFromC()方法的密码法则如下:
Java_com_himi_helloworld_MainActivity_getHelloFromC()
Java_(包名,包名使用'_'分割)_类名_Android(java)调用的方法名()
备注:jni.h文件作用是数据类型翻译,将JAVA语言的数据类型利用C的语法重新定义,实现2种不同的语法之间的数据类型转换。
• jni.h(导入进来的,NDK中platform有):
文件内容太多,截图一部分让大家感受一下
(5)上面准备好的hello.c 和jni.h都是在Win7系统下编写的,但是我们想让它在Android(Linux2.6.6)环境下运行,不得不介绍一个工具:NDK
搜索下载NDK,我的是win7 32位系统,下载的是android-ndk-r9c_x86.zip,大家看到了这是一个压缩文件,只要解压即可(无需安装),解压效果如下:
接下来要在环境变量中配置PATH路径,这样才能直接在Win7 系统的命令行下运行,我的配置完毕了,下面进入命令行窗口使用 "ndk-build",如下:
出现这样的问题,一方面说明ndk工具配置正确,另一方面说明没有正确运行。这个问题是因为:这需要在工程目录下运行命令行才能,什么工程呢?就是我们编写的Android工程”HelloWorld",让我们先找到”HelloWorld"的工程目录,如下:
然后,在上面的工程目录下,运行" ndk-build"的cmd命令,如下:
虽然,出现了警告,但是说明之前的错误解决了。现在出现这个问题是因为红色部分:我们的Android工程下jni文件夹下找不到Android.mk文件,该怎么办呢?我们自己在jni文件下创建这个Android.mk文件即可,如下:
新建完了Android.mk,但是内部的内容该写什么呢?不急,大家来到ndk的解压目录中docs(帮助文档)文件夹下,如下:
打开之后的效果图如下:
复制到Android工程的Android.mk文件下,如下:
修改之后,文件如下:
这时候我们再来运行"ndk-build"命令如下:
刷新工程,看到如下结果,Window下动态库文件(.dll) Linux下动态库文件(.so):
上面我们是在win7系统下,生成了可以在Linux系统下运行的代码libhellojni.so,这就是前面提到的交叉编译,这里使用的交叉编译的工具是NDK.
(6)接下来就是让java代码调用" libhellojni.so",进入MainActivity,如下:
(7)布署这个Android的"HelloWorld"工程到模拟器下,效果如下:
点击"问C要Hello",如下:
Android(java)学习笔记257:JNI之helloword案例(利用NDK工具)的更多相关文章
- 【Java学习笔记之十二】Java8增强的工具类:Arrays的用法整理总结
本文将整理 java.util.Arrays 工具类比较常用的方法: 本文介绍的方法基于JDK 1.7 之上. 1. asList方法 @SafeVarargs public static &l ...
- Java学习笔记43(打印流、IO流工具类简单介绍)
打印流: 有两个类:PrintStream,PrintWriter类,两个类的方法一致,区别在于构造器 PrintStream:构造方法:接收File类型,接收字符串文件名,接收字节输出流(Outpu ...
- Java学习笔记33(集合框架七:Collections工具类)
数组有工具类,方面操作数组 集合也有工具类:Collections 常用方法示例: package demo; import java.util.ArrayList; import java.util ...
- 0028 Java学习笔记-面向对象-Lambda表达式
匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...
- 《Java学习笔记(第8版)》学习指导
<Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...
- Android动画学习笔记-Android Animation
Android动画学习笔记-Android Animation 3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...
- Java学习笔记:语言基础
Java学习笔记:语言基础 2014-1-31 最近开始学习Java,目的倒不在于想深入的掌握Java开发,而是想了解Java的基本语法,可以阅读Java源代码,从而拓展一些知识面.同时为学习An ...
- Android 数字签名学习笔记
Android 数字签名学习笔记 在Android系统中,所有安装到系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系,如果一个permission的pro ...
- Java学习笔记4
Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...
- 【Java学习笔记之二十六】深入理解Java匿名内部类
在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意 ...
随机推荐
- php 时间戳 总结 今日,昨日,上周,本周,最近三个月,上季,本季,去年,最近七天,今年,最近三十天
if($time=="今日"){ $beginToday=mktime(0,0,0,date('m'),date('d'),date('Y')); $endToday=mktime ...
- 利用js加载本地图片预览功能
直接上代码: 经测试,除safari6包括6以下不支持,其他均可正常显示. 原因:safari6不支持filereader,同时不能使用IE滤镜导致失效. fix: 可以利用canvas,解决safa ...
- WebAPI下的如何实现参数绑定
本文将概述在WebAPI方式下将如何将参数绑定到一个action方法,包括参数是如何被读取,一系列规则决定特定环境采用的那种绑定方式,文章最后将给出一些实际的例子. Parameter binding ...
- ORACLE数据库多表关联查询效率问题解决方案
最近在做项目中遇到多表关联查询排序的效率问题(5张以上40W+数据的表),查询一次大概要20多秒,经过一番苦思冥想,处理方案如下: 1.软件设计初期,需要一对一关联的表应该设计在一张大表里,这样虽然字 ...
- oracle删除互相关联的记录
今天遇到一个问题,在数据库中删除一条记录,但是在删除的时候报错了,报出该记录已经被其他子记录引用,想了好久不知道怎么做,后来发现报错提示信息中会提示删除该记录时影响了那个约束条件,于是思路出来了: 1 ...
- Delphi-UpperCase 函数
函数名称 UpperCase 所在单元 System.SysUtils 函数原型 function UpperCase(const S: string): string; 函数功能 将字符串中所有的小 ...
- C语言笔记(枚举)
关于枚举,在我以前写程序的时候,几乎是没有使用过的,只是偶尔会在一下别人写的驱动库中有看到过.今天看了朱老师的视频,准备将枚举相关的东西总结一下. 一.关于枚举,你需要知道 (1)在C语言中就是一些符 ...
- Linux下设置静态IP和获取动态IP的方法
Linux下为机器设置静态IP地址: vim /etc/sysconfig/network-scripts/ifcfg-eth0 修改这个文件内容如下形式: # Intel Corporation ...
- SQL Server DAC 管理员专用连接
DAC 是Dedicated Administrator Connect 的缩写,是专用管理员连接通道,当SQL Server 因为资源不足而无法连接入系统的时候,管理员可通过该通道连接到数据,进行问 ...
- MVC linq语法分页
分页效果图: 表格下面的分页按钮样式是我自己做的一个样式,这4个按钮都是用同一张图片:这张图片是用ps做的. 接下来我们说一下怎么去做这个样式 第一css代码: ._HomePage,._Previo ...