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" >

    <TextView
        android: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();

	@Override
	protected 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.cpp

include $(BUILD_SHARED_LIBRARY)

5.  專案的檔案結構如下:

6. 執行結果

延伸話題:

在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.cpp

LOCAL_LDLIBS := -llog 

include $(BUILD_SHARED_LIBRARY)

Android JNI programming demo with Eclipse,布布扣,bubuko.com

时间: 2024-10-02 22:21:55

Android JNI programming demo with Eclipse的相关文章

android JNI 简单demo(2)之JNI demo 编写

android JNI 简单demo(2)之JNI demo 编写 一.搭建Cygwin 环境:http://blog.csdn.net/androidolblog/article/details/25559013 二.JNI 基本要素: 1.编写 含native 方法的java文件. 2.把该文件用javah 生成 Cygwin 编译库时要用到的头文件,既*.h 文件. 3.编写*.c 文件,在*.c文件中,实现 *.h 中的方法. 4.编写mk文件. 5.配置NDK环境. 6.用Cygwin

Android JNI 开发 Demo by NDK (native develop kit)

最近终于有了一些空闲时间,所以想着把之前的Android相关的项目整理一下,前几天整理了Android OCR 的项目, 今天就干脆再整理一下 NDK JNI调用. 关于Android 中通过JNI进行本地调用的配置与开发,已经在链接 http://blog.csdn.net/watkinsong/article/details/9849973 中给出了非常详细的说明. 请仔细阅读. 同时,关于Android 作OCR的说明,也已经 在 http://blog.csdn.net/watkinso

基于Eclipse的Android JNI层测试应用开发过程记录

前言 本文记录一个Java层与JNI层参数与数据交互的应用程序开发过程,为实现一个功能完整的带Java与JNI的应用程序打下基础.本文假设读者已搭建好Android的Eclipse与NDK开发环境,包括通过ADB连接手机的配置. 1. 构建基本的Android应用程序 1.1 引导界面配置 打开Eclipse,"File"->"New"->"Android Application Project",在弹出界面,配置如下(红色框表示不是

如何成功运行SDL官方提供的Android平台的Demo

如何成功运行SDL官方提供的Android平台的Demo 作者:雨水  日期:2014-4-30 编写说明:SDL的官方提供了一个Anroid的demo模板SDLActivity,无法直接运行,按照官方的文档操作过程中也会遇到很多问题,这里把我成功编译并运行的过程记录下来,希望对大家有所帮助! SDL简介:SDL是Simple DirectMedia Layer的缩写,它是一套开源的C语言跨平台多媒体开发库,提供了多种控制图像,声音等接口,广泛用于游戏,媒体播放器,模拟器开发等. 基本环境: 1

android JNI调用(转)

Android jni开发资料--NDK环境搭建 android开发人员注意了 谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK.而在NDKr7开始,Google的Windows版的NDK提供了一个ndk-build.cmd的脚本,这样,就可以直接利用这个脚本编译,而不需要使用Cygwin了.只需要为Eclipse Android工程添加一个Builders,而为Eclipse配置的builder,其实就是在

两分钟学会Android平台NDK编程(无须Eclipse和cygwin,可使用命令行打包多个so)

之前在进行cocos2dx开发时,已经详细介绍了如何将win32的c++代码移植到Android平台,当再次回顾时,发现一些基础的东西理解并不是很彻底,今天使用Android NDK提供的一个例子做一个简单的移植.在进行该demo前,请确认你已经配置了Android开发环境和安装了最新的Android NDK. 1.创建Android项目 创建一个Android项目 , 包名是com.example.hellojni,创建一个Activity作为程序进入的Acitivity,命名为HelloJn

Android jni 编程入门

本文将介绍如何使用eclipse和ndk-build来编写一个基于Android4.4版本的包含有.so动态库的安卓程序. 前提是已经安装和配置好了诸如SDK,NDK等编译环境.下面开始编程! 1 程序逻辑 我们要编写的程序包含两部分:java部分--负责界面和调用JNI native函数:JNI native 部分--负责native函数的具体实现(本文使用C语言). native 函数伪代码如下: ? 1 2 3 4 5 6 7 8 /* funtion: 传入两个整形变量,计算他们之和 r

Ubuntu下编译Android JNI实例全过程

第一步:保证make和gcc可用 在shell中输入make-v,不报错就是对的.(可参考http://wenku.baidu.com/view/d87586c24028915f804dc24a.html.) 在shell中输入gcc-v,不报错就是对的. 第二步:安装NDK 下载NDK后,设置环境变量: 将android-ndk的路劲加到环境变量PATH中:sudogedit /etc/environment 然后再让这个更改的环境变量立即生效:source /etc/environment

Android ListView分页加载(服务端+android端)Demo

Android ListView分页加载功能 在实际开发中经常用到,是每个开发者必须掌握的内容,本Demo给出了服务端+Android端的两者的代码,并成功通过了测试. 服务端使用MyEclipse,Android端使用Eclipse. 实现效果图: 服务端一共100条数据,共分四页,每页有25条数据. 源代码: 服务端: 需要导入图中这几个jar包. 在运行Android端代码前,需要开启服务端: 下面先给出服务端的代码: 类EmpDataSource: package com.android