Jni使用流程

来源:互联网 发布:js 获取数组最后一个 编辑:程序博客网 时间:2024/05/21 04:02

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<stdio.h>

#include<stdlib.h>

#include<lame.h>

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

引入log功能

#include<android/log.h>

#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编解码器的移植步骤

解压libmp3lamejni目录.

拷贝 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 <stdio.h>

      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());

原创粉丝点击