android JNI 经验分享
来源:互联网 发布:大数据为什么在贵州 编辑:程序博客网 时间:2024/06/07 09:11
转载请注明出处:http://blog.csdn.net/jack_chen_00/article/details/37522883
Demo所使用的源码地址:http://download.csdn.net/detail/chenjianjk/7604969
第一次接触JNI,网上相关资料零零散散,经过几天的实践终于算是会用了,总结下今天的经验分享给大家,希望对初学者有所帮助。
环境搭建
早期NDK编译环境的搭建是需要Cygwin + NDK配合才行,最初我也是按照这个方案来执行,环境搭建之繁琐真是让人无语,还好找到了更好的环境搭建方法,只需要用到 NDK 就可以,以下是我的搭建方法:1.下载NDK。
在Google的官方下载最新版的NDK,以下是下载网址http://developer.android.com
www.android-doc.com
www.toolib.net
2.Eclips的安装与配置。
我使用的IDE工具是Eclips,为了方便开发,需要安装CDT/ADT插件,如果你还没有学会怎么使用Eclips,你可以网上搜索以下Eclips的安装、使用方法,这里不做细节的介绍。3.JNI 数据类型。
JNI的目的是实现Java调用本地的C/C++方法,但是Java中的数据类型与C/C++的数据类型存在差异,不能直接使用,所以需要统一定义Java与C/C++的数据类型。JNI数据类型对照表参考网址:http://blog.csdn.net/zjc0888/article/details/6288602
4.Android.mk
在Android工程下的JNI目录中需要有一个Android.mk的文件,用来规定C/C++的编译规则,Android.mk与Linux下的Makefile功能类似,Android.mk是GNU Makefile的一部分,用过Makefile的人都知道,它是管理、编译、维护一个大型的源码工程必不可少的工具。Android.mk是Android定义的一种代码编译方式,它也有自己的一套编写规范,代码编译的规则都存放在Android.mk的文件里。想要使用JNI,就必须了解最基本的Android.mk的编写规范,读者可以参数下面的网址自学如果编写Android.mk文件。
参考网址:http://blog.csdn.net/cuijpus/article/details/5627248
创建Android工程
1. 创建应用程序。
在Eclips创建一个名称为JNI_DEMO的Android应用程序,在布局文件中新增一个按钮方便触发JNI 调用。
public class MainActivity extends Activity implements OnClickListener {Button mButton;private String TAG = "TEST";int i = 1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mButton = (Button)findViewById(R.id.button1);mButton.setOnClickListener(this);}@Overridepublic void onClick(View v) {Log.d(TAG, NativeUtils.getLocomotiveName());Log.d(TAG, NativeUtils.init(38400,"SD")+"");Log.d(TAG, NativeUtils.unInit()+"");Log.d(TAG, NativeUtils.start(0)+"");Log.d(TAG, NativeUtils.stop(0)+"");Log.d(TAG, NativeUtils.getStatus(1, 2)+"");}}
2.声明本地方法
package com.android.sms.util;public class NativeUtils {static {//读取代码库,需要先读取代码库才能调用库文件中的本地方法System.loadLibrary("test-jni");}public static native String getLocomotiveName();public static native int init(int baudRate, String storagePath);public static native int unInit();public static native int start(int fileId);public static native int stop(int fileId);public static native int getStatus(int cmd,int data);}
3.编写本地代码(C/C++)
在app工程目录下新建一个jni目录,在jni目录中新建testjni.c
#include <stdlib.h>#include <string.h>#include <stdio.h>#include <jni.h>#include <assert.h>#include<android/log.h>#define TAG "myDemo-jni" // 这个是自定义的LOG的标识#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__) // 定义LOGD类型#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__) // 定义LOGI类型#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__) // 定义LOGW类型#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__) // 定义LOGE类型#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__) // 定义LOGF类型JNIEXPORT jstring JNICALL native_getLocomotiveName(JNIEnv *env, jclass clazz){LOGD("native_getLocomotiveName.\n");return (*env)->NewStringUTF(env, "Hello world");}JNIEXPORT jint JNICALL native_init(JNIEnv *env, jclass clazz,jint baudRate, jstring storagePath){LOGD("native_init.\n");return baudRate;}JNIEXPORT jint JNICALL native_unInit(JNIEnv *env, jclass clazz){LOGD("native_unInit.\n");return 2;}JNIEXPORT jint JNICALL native_start(JNIEnv *env, jclass clazz, jint fileid){LOGD("native_start.\n");return 3;}JNIEXPORT jint JNICALL native_stop(JNIEnv *env, jclass clazz, jint fileid){LOGD("native_stop.\n");return 4;}JNIEXPORT jint JNICALL native_getStatus(JNIEnv *env, jclass clazz, jint cmd, jint data){LOGD("native_getStatus.\n");return 5;}#define JNIREG_CLASS "com/android/sms/util/NativeUtils"/*** Table of methods associated with a single class.*/static JNINativeMethod gMethods[] = {{ "getLocomotiveName", "()Ljava/lang/String;", (void*)native_getLocomotiveName },{ "init", "(ILjava/lang/String;)I", (void*)native_init },{ "unInit", "()I", (void*)native_unInit },{ "start", "(I)I", (void*)native_start },{ "stop", "(I)I", (void*)native_stop },{ "getStatus", "(II)I", (void*)native_getStatus },};/** Register several native methods for one class.*/static int registerNativeMethods(JNIEnv* env, const char* className, JNINativeMethod* gMethods, int numMethods){jclass clazz;clazz = (*env)->FindClass(env, className);if (clazz == NULL) {return JNI_FALSE;}if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {return JNI_FALSE;}return JNI_TRUE;}/** Register native methods for all classes we know about.*/static int registerNatives(JNIEnv* env){if (!registerNativeMethods(env, JNIREG_CLASS, gMethods, sizeof(gMethods) / sizeof(gMethods[0])))return JNI_FALSE;return JNI_TRUE;}/** Set some test stuff up.** Returns the JNI version on success, -1 on failure.*/JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){JNIEnv* env = NULL;jint result = -1;if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {return -1;}assert(env != NULL);if (!registerNatives(env)) {return -1;}/* success -- return valid version number */result = JNI_VERSION_1_4;return result;}
4.编写Android.mk
在jni目录中新建Android.mk文件。
## Copyright (C) 2008 The Android Open Source Project## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.## This makefile supplies the rules for building a library of JNI code for# use by our example of how to bundle a shared library with an APK.LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE_TAGS := optionalLOCAL_MODULE:= libtest-jniLOCAL_SRC_FILES:= testjni.cLOCAL_LDLIBS :=-llog LOCAL_SHARED_LIBRARIES := \libutilsLOCAL_STATIC_LIBRARIES :=LOCAL_C_INCLUDES += \$(JNI_H_INCLUDE)LOCAL_PRELINK_MODULE := falseinclude $(BUILD_SHARED_LIBRARY)
配置Eclips编译环境
1.解压已经下载好NDK压缩包
2.新建一个编译器
新建的编译器用于编译C/C++本地代码,新建编译器方法选中app工程目录 -> 右键选择Properties -> 选中Builders -> 点击New -> 双击Program -> 定义编译器。
3.编译代码
如果NDK编译器构建成功,在编译app的时候会在工程目录下自动生成一个obj的文件,里面有生成的*.so的动态库和一个编译生成的*.o中中间文件。如果配置不成功会有相应的错误提示。
0 0
- android JNI 经验分享
- 【分享】Android JNI实例
- 使用JNI开发的经验分享
- android分享支付经验分享
- Android蓝牙经验分享
- Android蓝牙经验分享
- Android SQLite 经验分享
- Android ShareSDK 分享经验
- Android -- 经验分享
- Android -- 经验分享
- Android -- 经验分享
- Android 经验分享
- Android JNI开发经验小记
- Android蓝牙经验分享一
- Android蓝牙经验分享二
- Android蓝牙经验分享一
- Android蓝牙经验分享二
- Android 开发建立经验分享...
- HttpPostedFile 和 HttpPostedFileBase 你真的了解嘛?
- leetcode: Restore IP Addresses
- 黑马程序员.Android攻城狮.JAVA应用.3.1.交通灯管理系统
- Vmware 虚拟机提示:无法打开磁盘***.vmdk,未能锁定文件,解决办法
- 黑马程序员 D9集合框架
- android JNI 经验分享
- block使用小结、在arc中使用block、如何防止循环引用
- PHP header()详解
- 博客搬迁至CSDN
- 手机网站开发及手机中图片加速显示img的Canvas方法
- 【性能测试】利用tcpcopy引流做模拟在线测试
- 在IT行业工作如何获得高薪?选择前沿的技术,把准方向,有技术有人缘
- 在vim中如何强制输入tab键
- xargs 命令