Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

ubuntu上最使用jni最简单易懂的例子

$
0
0

第一步:爆结果照,让你有坚持下去的信心



二、NDK解释

NDK全称:Native Development Kit。 
NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。 
NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。

NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。

三、NDK环境搭建

1、下载安装NDK-r10e并且配置好环境,地址http://developer.android.com/sdk/ndk/index.html,如果不清楚配置,可以先看我这篇博客 Android安全与逆向之在ubuntu上面搭建NDK环境http://blog.csdn.net/u011068702/article/details/53039584

2、打开Eclipse,新建一个Android工程(我的取名为FirstJni),在工程目录FirstJni下新建jni文件夹,该文件夹就用来保存NDK需要编译的文件代码等。
3、开始新建并配置一个Builder

(a)Project->Properties->Builders->New,新建一个FirstBuilder。 
(b)在弹出的【Choose configuration type】对话框,选择【Program】,点击【OK】: 
(c)在弹出的【Edit Configuration】对话框中,配置选项卡【Main】。 
在“Name“中输入新builders的名称(这个名字可以任意取)。

在“Location”中输入nkd-build.cmd的路径(这个是下载完ndkr10e后解压后的路径,这个建议放在根目录下面,路径不能有空格和中文)。根据各自的ndk路径设置,也可以点击“Browser File System…”来选取这个路径。 
在“Working Diretcoty”中输入TestNdk位置(也可以点击“Browse Workspace”来选取TestNdk目录)。如图1


第一个箭头是ndk目录下面的ndk-build.cmd

第二个箭头是选自己的项目

(d)继续在这个【Edit Configuration】对话框中,配置选项卡【Refresh】。如图2 
勾选“Refresh resources upon completion”, 
勾选“The entire workspace”, 
勾选“Recuresively include sub-folders”。


图2

(e)继续在【Edit Configuration】对话框中,配置选项卡【Build options】。 
勾选“After a “Clean””,(勾选这个操作后,如果你想编译ndk的时候,只需要clean一下项目 就开始交叉编译
勾选“During manual builds”, 
勾选“During auto builds”, 
勾选“Specify working set of relevant resources”。如图3

图3

点击“Specify Resources…”勾选FirstJni工程,点击”finish“。 点击“OK“,完成配置。 如图4


编译环境以及成功搭建完

四、demo的简单实现

 1.在FirstJni工程中新建一个JniClient.java
package com.example.firstjni;

public class JniClient {
	    static public native String AddStr(String strA, String strB);
	    static public native int AddInt(int a, int b);
}

2.生成 .h 的c++头文件

(1)用cmd命令定位到JniClient.class 所在目录,输入“javac JniClient.java“后回车,生成JniClinet.class文件(如果是用的Eclipse建的工程,在TestNdk\bin\classes\com\ndk\test目录下就已经有JniClinet.class文件了)。com.example.firstjni

(2)将JniClinet.class拷贝到FirstJni\bin\classes\com\example\firstjni目录,将cmd命令定位到FirstJni\bin\classes目录,输入”javah com.example.firstjni.JniClient“后回车,在FirstJni\bin\classes目录下就生成了C++头文件com_example_firstjni_JniClient.h

图片讲解如下:


com_example_firstjni_JniClient.h的文件内容如下:

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

#ifndef _Included_com_example_firstjni_JniClient
#define _Included_com_example_firstjni_JniClient
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_firstjni_JniClient
 * Method:    AddStr
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_firstjni_JniClient_AddStr
  (JNIEnv *, jclass, jstring, jstring);

/*
 * Class:     com_example_firstjni_JniClient
 * Method:    AddInt
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_example_firstjni_JniClient_AddInt
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif
3.在jni目录下新建一个Android.mk文件,其内容如下(关于mk文件需要注意,很重要,还有c和c++文件的mk文件还不一样,此处是调用c语言的mk文件,至于其他的怎么调用,这个自己去百度吧,在此就不多说了)

# Copyright (C) 2009 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.
#
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := FirstJni
LOCAL_SRC_FILES := com_example_firstjni_JniClient.c

include $(BUILD_SHARED_LIBRARY)

4. 将刚刚手动生成的com_example_firstjni_JniClient.h拷贝到FirstJni工程的jni目录下,

然后新建一个com_example_firstjni_JniClient.c文件完成头文件中函数的实现,其内容如下(本来想写两个方法的,现在只讲解第一个方法,返回一个字符串“HelloWorld from JNI ”,另一个方法是一个a+b的运算,方法写到这里,感兴趣的可以自己去研究):

com_example_firstjni_JniClient.c

#include "com_example_firstjni_JniClient.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifdef __cplusplus
extern "C"
{
#endif
/*
 * Class:     com_ndk_test_JniClient
 * Method:    AddStr
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_firstjni_JniClient_AddStr
  (JNIEnv *env, jclass arg, jstring instringA, jstring instringB)
{
    jstring str = (*env)->NewStringUTF(env, "I am chenyu, This is my first ubuntu jni!!!!");
    return str;
}

/*
* Class:     com_ndk_test_JniClient
* Method:    AddInt
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_example_firstjni_JniClient_AddInt
  (JNIEnv *env, jclass arg, jint a, jint b)
{
    return a + b;
}

#ifdef __cplusplus
}
#endif

此刻,当编辑com_ndk_test_JniClient.c并保存后,project下的—clean  一下工程,然后再去ndk-build项目,就可以生存响应的so文件


5.在MainActivity.java中完成对JniClient.java中函数的调用(首先静态加载动态链接so库):

package com.example.firstjni;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {

	 public String string1 = "I am chenyu ";
	 public String string2 = "this is my first ubuntu jni";
	 public int a = 3;
	 public int b = 5;
	 static {
		 System.loadLibrary("FirstJni");
	 }

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
        TextView  tv = new TextView(this);
        tv.setText(JniClient.AddStr(string1, string2)+"3 + 5 = " + JniClient.AddInt(a, b));
        setContentView(tv);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}

6.运行FirstJni工程,就出现了上面的爆图。

五、demo已经上传,需要的猛搓下面的地址

ubuntu上面使用jni例子  http://download.csdn.net/detail/u011068702/9675559   











作者:u011068702 发表于2016/11/7 21:43:17 原文链接
阅读:34 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>