当前位置: 代码迷 >> Android >> Android中兑现JNI调用笔记
  详细解决方案

Android中兑现JNI调用笔记

热度:88   发布时间:2016-05-01 20:05:46.0
Android中实现JNI调用笔记

实现在Android上jni编程,Android的c程序编译需放在Android2.0目录里利用Android的makefile进行编译。不像java下jni一样可以自己在其他地方编译然后在java程序中调用就可以了。

一:创建调用jni方法的android项目

1.在Eclipse下创建Android项目,如Jni_android,src目录下创建T1.java。
T1.java文件
-----------------------------
package org.aka;

import android.app.Activity;
import android.os.Bundle;

public class T1 extends Activity {
??? /** Called when the activity is first created. */
????
??? public native void display();
??? static {
??? ??? System.loadLibrary("goodluck");
??? }
????
??? @Override
??? public void onCreate(Bundle savedInstanceState) {
??????? super.onCreate(savedInstanceState);
??????? setContentView(R.layout.main);
??????? display();
??? }
}
-----------------------------
二:实现libgoodluck.so库
1.实现libgoodluck.so库,供T1调用,libgoodluck库中实现了dispaly方法。
2.jni实现时需知道,display在java中文件名,可通过javah获取。
方法:在终端里进入Jni_android所在的目录,如:我的是/home/xwp/workspace/Jni_android,进入生成bin文件的目录/home/xwp/workspace/Jni_android/bin,执行"javah -classpath . -jni org.aka.T1"(org.aka是包名)。生成了org_aka_T1.h文件。

org_aka_T1.h文件
-----------------------------
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_aka_T1 */

#ifndef _Included_org_aka_T1
#define _Included_org_aka_T1
#ifdef __cplusplus
extern "C" {
#endif
/*
?* Class:???? org_aka_T1
?* Method:??? display
?* Signature: ()V
?*/
JNIEXPORT void JNICALL Java_org_aka_T1_display
? (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

-----------------------------

2.创建goodluck.c文件,根据org_aka_T1.h知道,jni要实现的C程序名为“JNIEXPORT void JNICALL Java_org_aka_T1_display(JNIEnv *, jobject)”,(实现具体方法时需添加参数,JNIEnv *env, jobject jobj)。

3.goodluck.c文件

-----------------------------
#include <jni.h>
#include <stdio.h>
#define LOG_TAG "Testlib"
#undef LOG
#include <utils/Log.h>
JNIEXPORT void JNICALL Java_org_aka_T1_display(JNIEnv *env, jobject jobj)
{
??? LOGD("hello ,goodluck/n");
}

-----------------------------

4.goodluck.c需放到Android2.0目录下,利用Android提供的专用Android.mk进行编译,具体方法:
(1) cd <YourAndroid2.0目录>/development/
(2) mkdir goodluck
(3) 拷贝goodluck.c 到 goodluck目录下
(4) 创建Android.mk文件,可从其他目录下拷贝,然后修改为

Android.mk文件
-----------------------------

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_SRC_FILES:= goodluck.c
LOCAL_C_INCLUDES:=$(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES:=libutils
LOCAL_PRELINK_MODULE:=false
LOCAL_MODULE := libgoodluck
include $(BUILD_SHARED_LIBRARY)

-----------------------------

(5) cd <YourAndroid2.0目录>,执行make libgoodluck,屏幕输出:
-----------------------------
============================================
PLATFORM_VERSION_CODENAME=AOSP
PLATFORM_VERSION=AOSP
TARGET_PRODUCT=generic
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=MASTER
============================================
/bin/bash: 第 0 行: cd: development/tools/layoutopt/app/src/resources: 没有那个文件或目录
Install: out/host/linux-x86/bin/apriori
Install: out/host/linux-x86/bin/soslim
target Non-prelinked: libgoodluck (out/target/product/generic/symbols/system/lib/libgoodluck.so)
Install: out/target/product/generic/system/lib/libdl.so
Install: out/target/product/generic/system/lib/libc.so
Install: out/target/product/generic/system/lib/libstdc++.so
Install: out/target/product/generic/system/lib/libm.so
Install: out/target/product/generic/system/lib/liblog.so
Install: out/target/product/generic/system/lib/libz.so
Install: out/target/product/generic/system/lib/libcutils.so
Install: out/target/product/generic/system/lib/libutils.so
Install: out/target/product/generic/system/lib/libgoodluck.so

-----------------------------

(6) 生成的libgoodluck.so在 <YourAndroid2.0目录>/out/target/product/generic/system/lib/libgoodluck.so。

5.启动Android虚拟机,把libgoodluck.so拷贝到虚拟机/system/lib目录下,刚启动的虚拟机是不能对/system/lib进行写操作的,并且虚拟机中/system分区没有可使用空间。方法:
(1) 在终端下运行adb remount,如找不到adb命令,在~/.bashrc 中添加“export PATH=$PATH:/home/xwp/soft/linux_android/android-sdk-linux_86/tools”保存并重启终端。
(2) 释放虚拟机中/system分区空间,可删除/system/app/下用不到的apk文件,我删除的Camera.apk,腾出了部分空间。
(3) 上传libgoodluck.so到虚拟机/system/lib,进入到out/target/product/generic/system/lib/下,运行"adb push libgoodluck.so /system/lib"

6.在Eclipse中运行Jni_android项目,打开logcat,观察。出现了“Testlib??? hello,goodluck”这行log,表示JNI调用成功。

  相关解决方案