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

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



二、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://www.jb51.cc/article/p-npipsxev-kd.html

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 *,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,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已经上传,需要的猛搓下面的地址

相关文章

目录前言一、创建Hadoop用户二、更新apt和安装Vim编辑器三、...
原文连接:https://www.cnblogs.com/yasmi/p/5192694.html ...
电脑重启后,打开VirtualBox,发现一直用的虚拟机莫名的消失...
参见:https://blog.csdn.net/weixin_38883338/article/deta...
Ubuntu 18.04 LTS 已切换到 Netplan 来配置网络接口。Netpla...
介绍每个 Web 服务都可以通过特定的 URL 在 Internet 上访问...