Android JNI programming demo with Eclipse
用Eclipse 建立 JNI 的專案, 示範怎样在 JAVA 調用 cpp 的函數.
我們將建立一個名稱為 jnidemo的專案, 在主Activity 將調用一個名為libHello.so 的 cpp 函數庫的 getVersion() 的函數, 將其返回字串寫在主Activity 的TextView 上.
首先用Eclipse建立一個新的 Android Activity 專案. 其它選項都用預設值就能够.
1. 略微改动主活動配置 layout/activity_main.xml, 的在TextView 添�名為 title 的id(行12)以便稍候引用
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity" ><TextViewandroid:id="@+id/title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/hello_world" /></RelativeLayout>
2. 在MainActivity.java添�載入函式庫的動作並添加�一個native 函數名稱為 getVersion.
改寫例如以下:
package com.example.jnidemo;import android.os.Bundle;
import android.app.Activity;
import android.widget.TextView;public class MainActivity extends Activity {static {System.loadLibrary("Hello"); // Hello.dll (Windows) or libHello.so (Unixes)}private native String getVersion();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv = (TextView) findViewById(R.id.title);tv.setText( getVersion());}}
3. 新增一個 jni 的目錄. 在jni 底下添�一個名為 HelloJni.cpp 的文件.
/jni/HelloJni.cpp 內容例如以下
#include <jni.h>
#include <stdio.h>#define JNIREG_CLASS "com/example/jnidemo/MainActivity"//指定要注冊的类extern "C" JNIEXPORT jstring JNICALL native_getVersion(JNIEnv *env, jobject thisObj) {jstring szRet;szRet = env->NewStringUTF("V1.0");return szRet;
}/**********************************************************************************/
static JNINativeMethod gMethods[] = {{ "getVersion", "()Ljava/lang/String;", (void*)native_getVersion },
};/*
* Register several native methods for one class.
*/
static int registerNativeMethods(JNIEnv* env, const char* className,JNINativeMethod* gMethods, int numMethods)
{jclass clazz;clazz = env->FindClass( className);if (clazz == NULL) {return JNI_FALSE;}if (env->RegisterNatives( 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;
}
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{JNIEnv* env = NULL;jint result = -1;if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {return -1;}if (!registerNatives(env)) {//注冊return -1;}/* success -- return valid version number */result = JNI_VERSION_1_4;return result;
}//onUnLoad方法,在JNI组件被释放时调用
extern "C" void JNI_OnUnload(JavaVM* vm, void* reserved){
}
4. 在jni 底下添�一個名為 Android.mk 的文件.
/jni/Android.mk 內容例如以下
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)LOCAL_MODULE := libHello
LOCAL_SRC_FILES := HelloJni.cppinclude $(BUILD_SHARED_LIBRARY)
5. 專案的檔案結構例如以下:
6. 執行結果
Note:
編譯過程, 若發生例如以下錯誤
Cannot run program "ndk-build": Unknown reason
Error: Program "ndk-build" is not found in PATHPATH=[/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/lib/jvm/jdk1.6.0_38/bin]
請到Window->Preferences->Android->NDK->NDL Location 填入ndk 安裝路徑
若出現例如以下錯誤
/opt/android/android-ndk-r9b/ndk-build clean
Android NDK: WARNING: APP_PLATFORM android-19 is larger than android:minSdkVersion 17 in /{project_folder}/AndroidManifest.xml
請改动AndroidManifest.xml 的minSdkVersion 或是到File->Properties->Android 改選 SDK 的版本号
其它可能影響編譯結果的設定:
C/C++ Build Toolchain 必須選 Android GCC Compiler
確認C/C++ Build command 是 ndk-build
延伸話題:
在cpp中怎样把log 打印到logcat 的輸出呢? 在 cpp 檔及 Android.mk 要改动幾個地方
1. 在cpp 檔添� ALOGD, ALOGE 等函數的定義
#include <android/log.h>
#define LOG_TAG "JniDemo"
#define ALOGE(...) \__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__);
#define ALOGW(...) \__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__);
#define ALOGD(...) \__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__);
#define ALOGV(...) \__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__);
使用 debug level 的log輸出函數 ALOGD 範比例如以下
extern "C" JNIEXPORT jstring JNICALL native_getVersion(JNIEnv *env, jobject thisObj) {jstring szRet;szRet = env->NewStringUTF("V1.0");ALOGD("native_getVersion");return szRet;
}
2. 在 Android.mk 指定載入liblog.so 函數庫
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)LOCAL_MODULE := libHello
LOCAL_SRC_FILES := HelloJni.cppLOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY)
转载于:https://www.cnblogs.com/hrhguanli/p/3940172.html
Android JNI programming demo with Eclipse相关推荐
- ubuntu下的android JNI入门DEMO
在网上找的jni demo在对着练习的时候,总是多多少少报错. 所以把自己的摸索记录下来 环境: Ubuntu 10.04 LTS eclipse: http://developer.android. ...
- android项目模块导入eclipse编译报错,android环信demo导入eclipse编译出错
官网最新下载的android环信sdk,导入编译出错:java.lang.RuntimeException: Unable to instantiate application com.hyphena ...
- Android :JNI 回调demo
Android :JNI 回调demo 一.AndroidStudioProjects\jnicallbackdemo\app\src\main\java\com\example\jnicallbac ...
- Android Jni 调用
Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 Chap 3:javah命令帮助信息... 16 Chap 4:用javah产生一个.h文件... 17 Chap5:j ...
- Android JNI --函数调用大全
Chap1:JNI完全手册 最近在公司里做了一个手机的项目,需要JAVA程序在发送短信的时候和第三方的短信服务器连接.短信接口是用C++ 写的.琢磨了三天,大致搞懂了JNI的主体部分.先将心得整理,希 ...
- [转]Android JNI使用方法
本文转自:http://www.open-open.com/lib/view/open1324909652374.html 经过几天的努力终于搞定了android JNI部分,下面将我的这个小程序和大 ...
- Android JNI初试之环境搭建,最新方式的HelloWorld
前言 最近有个图片识别的需求.需要使用OpenCV,于是研究起了JNI,发现很多资料过旧.绕了大圈.踩了几个坑.总结一下. 什么是JNI Java Native Interface , 实现Java和 ...
- Android JNI开发入门之一
JNI在Android系统中有着广泛的应用.Android系统底层都是C/C++实现的,上层提供的API都是Java的,Java通过JNI调用底 层的实现.比如:Android API多媒体接口Med ...
- Android JNI简单实例(android 调用C/C++代码)
转载自 xiechengfa 最终编辑 xiechengfa Android JNI简单实例关键字: android.jni Android的jni实例 android 的应用程序(Dalvik VM ...
最新文章
- itmz文件如何打开_如何使用proteus8打开低版本proteus7的仿真文件?
- postman可以测试websocket吗_小海塔罗娱乐测试2021年可以脱单吗?
- Vue—基础概念—组建化
- asp.net core 3.0 中使用 swagger
- Spring JDBC和JdbcTemplate CRUD与DataSource示例
- 蓝牙技术联盟宣布开放蓝牙网关架构 IoT设备无须Wi-Fi即可联网
- 搭建Harbor docker镜像仓库
- Java10的新特性
- linux Boot目录满了之后的解决方法
- JS If...Else
- 网页编码utf8 gb2312 gbk的区别
- Linux下模拟多线程的并发并发shell脚本
- Java 拦截器自定义(添加响应头)
- 人工智能真的具有创造力?
- 【WeNews】三胞债务重组方案出炉 650亿元金融债务如何化解
- Fractions (水)
- 相关矩阵 Correlation matrix
- 零数科技成功通过CMMI3级认证,软件研发能力获国际认可
- 解决中文乱码问题:使用编码转换工具
- 什么是ui设计师:ui设计学什么内容
热门文章
- Oracle 11g 数据恢复 数据误删除后的恢复 0、执行 select log_mode from v$database;查看是否为归档模式 1、确定删除时间和被删除的表 04-23,GR
- 评《货币战争》:问苍茫大地谁主沉浮? 第一次转这样的帖子
- JAVA程序员代表大众车,C++程序员代表捷豹,看看各类程序员们代表着什么车
- Chalubo僵尸网络来袭 IOT设备或将受到DDoS攻击
- 20165334 《java程序设计》第5周学习总结
- MongoDB联合查询 -摘自网络
- Erlang编程语言的一些痛点
- cacti+nagios整合(未成)
- postgresql 执行计划理解
- document.all用法