Jni使用流程

Jni使用流程:

1.       工程下建立一个jni目录,目录下建立一个Android.mk文件(可以到ndk文档中copy

2.       java 文件中建立需要的 native方法

3.       到工程的bin/classes目录下用javah 生成所要的头文件

4.       将头文件copyjni目录下,再建立一个.c文件在该文件中实现头文件中的方法

5.       /cygdrive/d/workspace/工程名 ndk-build 编译

示例:

Android.mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := Hello  生成的库文件的名称

LOCAL_SRC_FILES := bitstream.c fft.c id3tag.c mpglib_interface.c presets.c  quantize.c   reservoir.c tables.c  util.c  VbrTag.c encoder.c  gain_analysis.c lame.c  newmdct.c   psymodel.c quantize_pvt.c set_get.c  takehiro.c vbrquantize.c version.c Hello.c

需要被编译的C文件

LOCAL_LDLIBS += -llog  加入log功能

include $(BUILD_SHARED_LIBRARY)

      实现头文件的.c文件

#include

#include

#include

#include "com_itheima_lame_LameActivity.h"加入有本地方法签名的头文件

引入log功能

#include

#define LOG_TAG "System.out.c"

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

 

Jni使用过程中出现的错误:

 

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.

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.javac代码库没有找到,java代码没有引入库文件

Caused by: java.lang.UnsatisfiedLinkError: Library Hell0 not found

 

静态加载代码库的时候 代码库没有找到.

 

5.c代码函数签名出现错误

Caused by: java.lang.UnsatisfiedLinkError: hello_from_c

 

6.逻辑性的错误, 使用了已经回收的内存空间, 访问了不可以被访问的内存空间,

修改了不能被修改的内存空间

 

断点. ndk-gdb

通过log 方式来观察程序执行流程

 

7.c语言中某些头文件没有引入

 

8.耗时的操作要开子线程,线程忘记.start()

 

ndk开发的中文乱码问题:

1.低版本ndk 不支持中文 ndk-r4-crystal

iso-8859-1 转码

2.高版本中,只需要将文件保存为UTF8

 

java中的string转化为c语言中的字符串

char*Jstring2CStr(JNIEnv* env, jstring jstr) {

    char* rtn = NULL;

    jclass clsstring = (*env)->FindClass(env, "java/lang/String");

    jstring strencode = (*env)->NewStringUTF(env, "GB2312");

    jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes",

            "(Ljava/lang/String;)[B");

    jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid,

            strencode); // String .getByte("GB2312");

    jsize alen = (*env)->GetArrayLength(env, barr);

    jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);

    if (alen > 0) {

        rtn = (char*) malloc(alen + 1); //"\0"

        memcpy(rtn, ba, alen);

        rtn[alen] = 0;

    }

    (*env)->ReleaseByteArrayElements(env, barr, ba, 0); //

    return rtn;

}

 javap 生成native方法的签名

javap –s 全类名

 

开发环境的搭建:

第一个工具:

NDK (native develop kits) 

交叉编译的工具链:

交叉编译: 在一个平台(处理器,操作系统) 编译出来另外一个平台下可以运行的代码.

windows AMD intel x86 架构-> 手机 android arm处理器

 

.c .java

1. 编译  把源代码(高级语言)编译成一个低级语言 (汇编语言)

2. 连接  根据具体平台的特性,(cpu的类型 x86 arm,操作系统的类型)

         连接成一个可以执行的二进制可执行的程序.

 

第二个工具:

cygwin: windowslinux环境的模拟器.

cygwin的安装目录 不能有空格,最好不要中文

 

第三个工具:

cdt : c/c++ develop tools  (主要是用来让cc++代码 完成高亮显示的作用)

adt : android develop tools

 

环境变量的作用: 方便的在任何目录下 都可以使用 指定目录里面的工具

       C:\cygwin\etc 下找到profile文件

PATH="/usr/local/bin:/usr/bin:/cygdrive/d/android/android-ndk-r7b:${PATH}"

ndk-build所在目录加入到环境变量中即可

 

Lame编解码器的移植步骤

解压libmp3lame jni目录.

拷贝 lame.h

创建Android.mk

 

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := mp3lame

LOCAL_SRC_FILES := bitstream.c fft.c id3tag.c mpglib_interface.c presets.c  quantize.c   reservoir.c tables.c  util.c  VbrTag.c encoder.c  gain_analysis.c lame.c  newmdct.c   psymodel.c quantize_pvt.c set_get.c  takehiro.c vbrquantize.c version.c

include $(BUILD_SHARED_LIBRARY)

 

 

删除 GNU autotools, Makefile.am Makefile.in libmp3lame_vc8.vcproj logoe.ico depcomp, folders i386 等无用文件

编辑 jni/utils.h,

extern ieee754_float32_t fast_log2(ieee754_float32_t x);

替换为 extern float fast_log2(float x);

 

编译库文件

 

不用jni运行C语言

c语言开发程序

 

1.下载编译器和链接器软件.Sourcery G++ Lite Edition for ARM.

       arm-none-linux-gnueabi-gcc.exe是编译命令

       bin/arm-none-linux-gnueabi-ld.exe是链接命令

2.编写c源文件

       #include

       int main()

       {

              printf("Hello, Android!\n");

              return 0;

       }

3.编译hello.c源文件

       进入cmd

       执行 arm-none-linux-gnueabi-gcc HelloWorld.c -static -o hellostatic

4.hellostatic文件传输手机

       adb push hellostatic /data/data/hellostatic

5.改变文件的授权

       adb shell chmod 777 /data/data/hellostatic

6.运行程序

       adb shell

       cd /data/data

       ./hellostatic

7.查看执行结果

在代码中运行二进制文件,即C语言

Process  process = Runtime.getRuntime().exec("date");

               InputStream is = process.getInputStream();

               DataInputStream dis = new DataInputStream(is);

               String result ;

               StringBuilder sb = new StringBuilder();

                while((result = dis.readLine())!=null){

                       sb.append(result);

                       sb.append("\n");

                }

               System.out.println(sb.toString());

你可能感兴趣的:(Android)