第一个工具:
NDK (native develop kits)
交叉编译的工具链:
交叉编译: 在一个平台(处理器,操作系统)下 编译出来另外一个平台下可以运行的代码.
windows AMD intel x86 架构-> 手机 android arm处理器
之前想要访问是这样:$ ./ndk-build
环境变量的作用: 方便的在任何目录下 都可以使用 指定目录里面的工具
之前必须在liunx下,不过r7b也支持windows,不过现在它正在开发中,不过它
不是很稳定。
.c .java
1. 编译 把源代码(高级语言)编译成一个低级语言 (汇编语言)
2. 连接 根据具体平台的特性,(cpu的类型 x86 arm,操作系统的类型)
把低级语言连接成一个可以执行的二进制可执行的程序.
第二个工具:
cygwin: windows下linux环境的模拟器.
cygwin的安装目录 不能有空格,最好不要中文
第三个工具:
cdt : c/c++ develop tools (主要是用来让c和c++代码 完成高亮显示的作用)
adt : android develop tools
JNI步骤:
1.创建一个android工程
2.JAVA代码中写声明native 方法 public native String helloFromJNI();
3. 创建jni目录,编写c代码,方法名字要对应
4.编写Android.mk文件
5.Ndk编译生成动态库
6.Java代码load 动态库.调用native代码
Android.mk告诉编译器,以什么样的规则去编译C代码。
chen@chen-THINK /cygdrive/e/androidworkspace/ndkhelloworld/jni
$ ndk-build
Cygwin : Generating dependency file converter script
Compile thumb : Hello <= Hello.c
SharedLibrary : libHello.so
Install : libHello.so => libs/armeabi/libHello.so
chen@chen-THINK /cygdrive/e/androidworkspace/ndkhelloworld/jni
本地代码里面的方法名里面就有代码。
javah生成JNI文件的签名。因为我们自己写方法签名太麻烦了,所以我们可以直接用javah去
自动生成,非常牛逼。如果有包名,要有相应的文件夹。
mk文件:交叉编译器编译C/c++代码,依赖的配置文件,linux理makefile的语法
的子集。
ndk-build clean,清除缓存。obj目录,libs目录,手工给它删除。
来这找:
F:\安卓笔记\JNI\2\ziliao\android-ndk-r7b\docs\ANDROID-MK.html
文件可以知道怎么写。
JNI开发中常见的错误:
LOCAL_PATH := $(call my-dir)
# 交叉编译器 在编译c代码/c++代码依赖的配置文件 linux下 makefile的语法的子集
# 获取当前Android.mk的路径
#变量的初始化操作 特点: 不会重新初始化LOCAL_PATH 的变量
include $(CLEAR_VARS)
#libHello.so 加lib前缀 .so后缀 makefile的语法约定的
LOCAL_MODULE := libHello
LOCAL_SRC_FILES := Hello.c
include $(BUILD_SHARED_LIBRARY)
ndk开发常见错误
1. android.mk文件不存在
$ ndk-build
Android NDK: Your APP_BUILD_SCRIPT points to an unknown file: ./jni/Android.mk
/cygdrive/h/heima6/jni2/ziliao/android-ndk-r7b/build/core/add-application.mk:133: *** Android NDK: Aborting... 。 停止。
2.android.mk文件 的配置信息有错误
$ ndk-build
/cygdrive/h/heima6/jni2/ziliao/android-ndk-r7b/build/core/build-shared-library.mk:23:
*** Android NDK: Missing LOCAL_MODULE before including BUILD_SHARED_LIBRARY in jni/Android.mk 。 停止。
3.c代码 语法出现错误,编译不通过 Error 1. C语言错误为依赖错误,一般第一个出现错误,之后的就都错了。
只需要修复第一个错误即可。
Compile thumb : Hello <= Hello.c
jni/Hello.c: In function 'Java_cn_itcast_ndk_DemoActivity_helloFromC':
jni/Hello.c:21: error: 'ctr' undeclared (first use in this function)
jni/Hello.c:21: error: (Each undeclared identifier is reported only once
jni/Hello.c:21: error: for each function it appears in.)
jni/Hello.c:21: error: expected ';' before 'c'
/cygdrive/h/heima6/jni2/ziliao/android-ndk-r7b/build/core/build-binary.mk:240: recipe for target `obj/local/armeabi/objs/Hello/Hello.o' failed
make: *** [obj/local/armeabi/objs/Hello/Hello.o] Error 1
4.java层c代码库没有找到
Caused by: java.lang.UnsatisfiedLinkError: Library Hell0 not found
静态加载代码库的时候 代码库没有找到.
5.c代码函数签名出现错误
Caused by: java.lang.UnsatisfiedLinkError: hello_from_c
6.逻辑性的错误, 使用了已经回收的内存空间, 访问了不可以被访问的内存空间,
修改了不能被修改的内存空间
断点. ndk-gdb
通过log 方式来观察程序执行流程 (NDK本身支持的)
Android.mk文件增加LOCAL_LDLIBS += -llog
C代码中增加
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
LOGI("info\n");
LOGD("debug\n");
学会开发OPenGL.
复习 :
第一步:
//第一步
public native String getStringFromC();
第二步:
E:\androidworkspace\ndk-utf\bin\classes>javah cn.itcast.utf.DemoActivity
第三步:
把cn_itcast_utf_DemoActivity.h copy到jni的目录下。
第四步:
建立C文件
#include <stdio.h>
#include <jni.h>
#include "cn_itcast_utf_DemoActivity.h"
JNIEXPORT jstring JNICALL Java_cn_itcast_utf_DemoActivity_getStringFromC
(JNIEnv * env, jobject obj){
return (*env)->NewStringUTF(env,"你好中国");
}
第五步:在JNI目录下建立一个Android.mk,否则无法编译。
用ndk-build进行编译。
#mk文件:交叉编译器编译C/c++代码,依赖的配置文件,linux理makefile的语法 的子集。
#获取当前Android.mk的路径。
LOCAL_PATH := $(call my-dir)
#变量初始化操作 特点:不会重新初始化LOCAL_PATH的变量。
include $(CLEAR_VARS)
#生成so文件的名字。 libHello.so,这样加也是linux下makefile语法所约定的。
LOCAL_MODULE := Hello
LOCAL_SRC_FILES := Hello.c
include $(BUILD_SHARED_LIBRARY)
//第六步,最后一步,加载类库。
static{
System.loadLibrary("Hello");
}
高版本解决中文乱码问题:
先把Hello.c里面的东西全部copy出来,
把Hello.c的编码变成UTF-8,然后再copy进去 。
低版本:
new String(getStringFromC().getBytes("iso-8859-1"),"utf-8");
ndk开发的中文乱码问题:
1.低版本ndk 不支持中文 ndk-r4-crystal
iso-8859-1 转码
//重要的课程开始啊。。。。。。。。。。。。。。。。。。
java传递数据给C,然后C再返回给JAVA。
有参数的方法。默认方法签名里面有都会有两个默认参数。
如果代码有更改就用ndk-build clean,然后再重建,还要清除项目class文件。
(JNIEnv * env, jobject obj)
第一个参数:指的是java虚拟机结构体C实现的指针包含的有很多JNI方法。
第二个参数:代表的是调用C代码的JAVA对象代表的是DataProvider对象。
如果是静态方法,第二个参数变成了 jclass clazz 它是指实例化后的对象。
比较高级一点的东西,让C代码调用JAVA的代码。
1. 当c代码接受到特定的消息 让c代码通知 java代码
2. c程序员 c代码想复用java里面的函数和方法
第一、E:\androidworkspace\ndkcallback\bin\classes>javah cn.itcast.ndkcallback.DataProv
ider
方法签名:
E:\androidworkspace\ndkcallback\bin\classes>javap -s cn.itcast.ndkcallback.DataP
rovider
Compiled from "DataProvider.java"
public class cn.itcast.ndkcallback.DataProvider extends java.lang.Object{
public cn.itcast.ndkcallback.DataProvider();
Signature: ()V
public void helloFromJava();
Signature: ()V
public int Add(int, int);
Signature: (II)I
public void printString(java.lang.String);
Signature: (Ljava/lang/String;)V
public static void printStaticStr(java.lang.String);
Signature: (Ljava/lang/String;)V
public native void callmethod1();
Signature: ()V
public native void callmethod2();
Signature: ()V
public native void callmethod3();
Signature: ()V
public native void callmethod4();
Signature: ()V
}
//为了避免现实中出现这种场景:
在这个里面调用native里面的方法,应该把所有的native方法放在一个类中。
阿里旺旺 :
登陆的具体实现 c/c++
socket http
int login(char* username,char * password){
//开启一个socket 连接服务器 , 把username 和 password传给服务器.
//服务器返回 200 登陆成功
//服务器返回404 登陆失败
}
public native int Login(String username, String pwd);
javah 生成native方法的签名
jint Java_xxx_xxx_xxx_xxx_Login(JNIENV* env , jobject obj , jstring username, jstring pwd){
char* cusername = JStr2Cstr();
char* cpwd = JStr2Cstr();
int result = login(cusername ,cpwd);
if(result == 200){
}
}
kiss : keep it simaple stupid
int String byte[]
int[]
1,2,3,4,5
c代码写文件
java读文件
java jni 粘合剂 胶水
c工程实现 具体的代码
jni native ->jni ->.c
1. 当c代码接受到特定的消息 让c代码通知 java代码
2. c程序员 c代码想复用java里面的函数和方法
NDK (native develop kits)
交叉编译的工具链:
交叉编译: 在一个平台(处理器,操作系统)下 编译出来另外一个平台下可以运行的代码.
windows AMD intel x86 架构-> 手机 android arm处理器
之前想要访问是这样:$ ./ndk-build
环境变量的作用: 方便的在任何目录下 都可以使用 指定目录里面的工具
之前必须在liunx下,不过r7b也支持windows,不过现在它正在开发中,不过它
不是很稳定。
.c .java
1. 编译 把源代码(高级语言)编译成一个低级语言 (汇编语言)
2. 连接 根据具体平台的特性,(cpu的类型 x86 arm,操作系统的类型)
把低级语言连接成一个可以执行的二进制可执行的程序.
第二个工具:
cygwin: windows下linux环境的模拟器.
cygwin的安装目录 不能有空格,最好不要中文
第三个工具:
cdt : c/c++ develop tools (主要是用来让c和c++代码 完成高亮显示的作用)
adt : android develop tools
JNI步骤:
1.创建一个android工程
2.JAVA代码中写声明native 方法 public native String helloFromJNI();
3. 创建jni目录,编写c代码,方法名字要对应
4.编写Android.mk文件
5.Ndk编译生成动态库
6.Java代码load 动态库.调用native代码
Android.mk告诉编译器,以什么样的规则去编译C代码。
chen@chen-THINK /cygdrive/e/androidworkspace/ndkhelloworld/jni
$ ndk-build
Cygwin : Generating dependency file converter script
Compile thumb : Hello <= Hello.c
SharedLibrary : libHello.so
Install : libHello.so => libs/armeabi/libHello.so
chen@chen-THINK /cygdrive/e/androidworkspace/ndkhelloworld/jni
本地代码里面的方法名里面就有代码。
javah生成JNI文件的签名。因为我们自己写方法签名太麻烦了,所以我们可以直接用javah去
自动生成,非常牛逼。如果有包名,要有相应的文件夹。
mk文件:交叉编译器编译C/c++代码,依赖的配置文件,linux理makefile的语法
的子集。
ndk-build clean,清除缓存。obj目录,libs目录,手工给它删除。
来这找:
F:\安卓笔记\JNI\2\ziliao\android-ndk-r7b\docs\ANDROID-MK.html
文件可以知道怎么写。
JNI开发中常见的错误:
LOCAL_PATH := $(call my-dir)
# 交叉编译器 在编译c代码/c++代码依赖的配置文件 linux下 makefile的语法的子集
# 获取当前Android.mk的路径
#变量的初始化操作 特点: 不会重新初始化LOCAL_PATH 的变量
include $(CLEAR_VARS)
#libHello.so 加lib前缀 .so后缀 makefile的语法约定的
LOCAL_MODULE := libHello
LOCAL_SRC_FILES := Hello.c
include $(BUILD_SHARED_LIBRARY)
ndk开发常见错误
1. android.mk文件不存在
$ ndk-build
Android NDK: Your APP_BUILD_SCRIPT points to an unknown file: ./jni/Android.mk
/cygdrive/h/heima6/jni2/ziliao/android-ndk-r7b/build/core/add-application.mk:133: *** Android NDK: Aborting... 。 停止。
2.android.mk文件 的配置信息有错误
$ ndk-build
/cygdrive/h/heima6/jni2/ziliao/android-ndk-r7b/build/core/build-shared-library.mk:23:
*** Android NDK: Missing LOCAL_MODULE before including BUILD_SHARED_LIBRARY in jni/Android.mk 。 停止。
3.c代码 语法出现错误,编译不通过 Error 1. C语言错误为依赖错误,一般第一个出现错误,之后的就都错了。
只需要修复第一个错误即可。
Compile thumb : Hello <= Hello.c
jni/Hello.c: In function 'Java_cn_itcast_ndk_DemoActivity_helloFromC':
jni/Hello.c:21: error: 'ctr' undeclared (first use in this function)
jni/Hello.c:21: error: (Each undeclared identifier is reported only once
jni/Hello.c:21: error: for each function it appears in.)
jni/Hello.c:21: error: expected ';' before 'c'
/cygdrive/h/heima6/jni2/ziliao/android-ndk-r7b/build/core/build-binary.mk:240: recipe for target `obj/local/armeabi/objs/Hello/Hello.o' failed
make: *** [obj/local/armeabi/objs/Hello/Hello.o] Error 1
4.java层c代码库没有找到
Caused by: java.lang.UnsatisfiedLinkError: Library Hell0 not found
静态加载代码库的时候 代码库没有找到.
5.c代码函数签名出现错误
Caused by: java.lang.UnsatisfiedLinkError: hello_from_c
6.逻辑性的错误, 使用了已经回收的内存空间, 访问了不可以被访问的内存空间,
修改了不能被修改的内存空间
断点. ndk-gdb
通过log 方式来观察程序执行流程 (NDK本身支持的)
Android.mk文件增加LOCAL_LDLIBS += -llog
C代码中增加
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
LOGI("info\n");
LOGD("debug\n");
学会开发OPenGL.
复习 :
第一步:
//第一步
public native String getStringFromC();
第二步:
E:\androidworkspace\ndk-utf\bin\classes>javah cn.itcast.utf.DemoActivity
第三步:
把cn_itcast_utf_DemoActivity.h copy到jni的目录下。
第四步:
建立C文件
#include <stdio.h>
#include <jni.h>
#include "cn_itcast_utf_DemoActivity.h"
JNIEXPORT jstring JNICALL Java_cn_itcast_utf_DemoActivity_getStringFromC
(JNIEnv * env, jobject obj){
return (*env)->NewStringUTF(env,"你好中国");
}
第五步:在JNI目录下建立一个Android.mk,否则无法编译。
用ndk-build进行编译。
#mk文件:交叉编译器编译C/c++代码,依赖的配置文件,linux理makefile的语法 的子集。
#获取当前Android.mk的路径。
LOCAL_PATH := $(call my-dir)
#变量初始化操作 特点:不会重新初始化LOCAL_PATH的变量。
include $(CLEAR_VARS)
#生成so文件的名字。 libHello.so,这样加也是linux下makefile语法所约定的。
LOCAL_MODULE := Hello
LOCAL_SRC_FILES := Hello.c
include $(BUILD_SHARED_LIBRARY)
//第六步,最后一步,加载类库。
static{
System.loadLibrary("Hello");
}
高版本解决中文乱码问题:
先把Hello.c里面的东西全部copy出来,
把Hello.c的编码变成UTF-8,然后再copy进去 。
低版本:
new String(getStringFromC().getBytes("iso-8859-1"),"utf-8");
ndk开发的中文乱码问题:
1.低版本ndk 不支持中文 ndk-r4-crystal
iso-8859-1 转码
//重要的课程开始啊。。。。。。。。。。。。。。。。。。
java传递数据给C,然后C再返回给JAVA。
有参数的方法。默认方法签名里面有都会有两个默认参数。
如果代码有更改就用ndk-build clean,然后再重建,还要清除项目class文件。
(JNIEnv * env, jobject obj)
第一个参数:指的是java虚拟机结构体C实现的指针包含的有很多JNI方法。
第二个参数:代表的是调用C代码的JAVA对象代表的是DataProvider对象。
如果是静态方法,第二个参数变成了 jclass clazz 它是指实例化后的对象。
比较高级一点的东西,让C代码调用JAVA的代码。
1. 当c代码接受到特定的消息 让c代码通知 java代码
2. c程序员 c代码想复用java里面的函数和方法
第一、E:\androidworkspace\ndkcallback\bin\classes>javah cn.itcast.ndkcallback.DataProv
ider
方法签名:
E:\androidworkspace\ndkcallback\bin\classes>javap -s cn.itcast.ndkcallback.DataP
rovider
Compiled from "DataProvider.java"
public class cn.itcast.ndkcallback.DataProvider extends java.lang.Object{
public cn.itcast.ndkcallback.DataProvider();
Signature: ()V
public void helloFromJava();
Signature: ()V
public int Add(int, int);
Signature: (II)I
public void printString(java.lang.String);
Signature: (Ljava/lang/String;)V
public static void printStaticStr(java.lang.String);
Signature: (Ljava/lang/String;)V
public native void callmethod1();
Signature: ()V
public native void callmethod2();
Signature: ()V
public native void callmethod3();
Signature: ()V
public native void callmethod4();
Signature: ()V
}
//为了避免现实中出现这种场景:
在这个里面调用native里面的方法,应该把所有的native方法放在一个类中。
阿里旺旺 :
登陆的具体实现 c/c++
socket http
int login(char* username,char * password){
//开启一个socket 连接服务器 , 把username 和 password传给服务器.
//服务器返回 200 登陆成功
//服务器返回404 登陆失败
}
public native int Login(String username, String pwd);
javah 生成native方法的签名
jint Java_xxx_xxx_xxx_xxx_Login(JNIENV* env , jobject obj , jstring username, jstring pwd){
char* cusername = JStr2Cstr();
char* cpwd = JStr2Cstr();
int result = login(cusername ,cpwd);
if(result == 200){
}
}
kiss : keep it simaple stupid
int String byte[]
int[]
1,2,3,4,5
c代码写文件
java读文件
java jni 粘合剂 胶水
c工程实现 具体的代码
jni native ->jni ->.c
1. 当c代码接受到特定的消息 让c代码通知 java代码
2. c程序员 c代码想复用java里面的函数和方法