Android Jni之Helloworld

原创 2016年05月30日 23:52:00

一、搭建NDK环境

NDK可以自己下载好,然后布置一下环境变量。不过我这里有个更加简便的方法。在Android studio2.2及更高版本中可以像插件那样安装NDK了。
设置流程如下:
点开File->Setting,弹出Setting窗口。
NDK环境搭建
如图所示,在setting -> Appearance&Behavior -> System Setting -> Android SDK -> SDK Tools(视图右边),选择CMake、LLDB、NDK这三个下载。然后一边静静地等它下载安装。

如果你是建好工程再下载NDK,你还要在File ->Project Structure里面设置一下NDK地址。这里直接按“Select default NDK”就可以了。
selectNDK
它会自己生成路径:D:\Android\Sdk\ndk-bundle(这是我电脑NDK的地址)
并且会在local.properties里自动生成一行ndk目录地址。
生成NDK地址

在gradle.properties里面添加
android.useDeprecatedNdk=true

gradle.properties配置
至此,你可以愉快地编写Jni了。

二、Jni编写

1)编写Java接口

在项目里新建一个Java类。

public class Jni {

   public native String say(String str);

}

注意这里用到的是“native”修饰。

2)编写c/c++接口及代码

Android studio有个Terminal工具,对应Windows系统的cmd窗口。
在cmd里面cd进入项目的Java文件夹里面,因为Java文件夹里面的是对应包名
package com.example.jnitest;
输入javah -jni com.example.jnitest.Hello然后生成.h文件。
这里写图片描述

项目目录下就多了一个com_example_jnitest_Jni.h文件。
这里写图片描述

这个就是c/c++的头文件

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

#ifndef _Included_com_example_jnitest_Jni
#define _Included_com_example_jnitest_Jni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_jnitest_Jni
 * Method:    say
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_jnitest_Jni_say
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

新建JNI文件夹
新建JNI文件夹

然后把com_example_jnitest_Jni.h文件拉进去
这里写图片描述

在jni目录里新建c/c++源码文件

#include <stdio.h>
#include <stdlib.h>
#define TAG "JNI" //自定义的变量
#include <android/log.h>
#define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, TAG ,__VA_ARGS__)
#include "com_example_jnitest_Jni.h"
JNIEXPORT jstring JNICALL Java_com_example_jnitest_Jni_say
        (JNIEnv *env, jobject, jstring str) {
           LOGD("This is JNI");
    return str;
}

上面的c/c++源码#include "com_example_jnitest_Jni.h" 就是引入刚刚生成的.h文件。Java_com_example_jnitest_Jni_say是对应Java类里的say方法。这个名字是要固定的格式写的,文件目录-文件名-方法名,如果你取其他名称也需准守起名规则。
总体的目录结构如下:
目录结构

3)生成so文件

打开app Module的build.gradle文件,在defaultConfig节点加入NDK的配置信息。

      ndk {
            moduleName "HelloWorld"     //so文件名
            ldLibs "log", "z", "m"      //添加系统库文件
            abiFilters "armeabi", "armeabi-v7a", "x86"   //d对应芯片结构
        }

moduleName是你的so文件名,lbLibs附加系统库文件,abIlity添加你要生成的库对应的芯片架构。
这里添加了log,在这个项目代码对应是

#define TAG "JNI" //自定义的变量
#include <android/log.h>
#define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, TAG ,__VA_ARGS__)
LOGD("This is JNI");

这个是在c/c++源码里添加log日记。

NDK配置信息

布置好了就可以编译了。
编译Jni
在工具来点击编译按钮,或者在Build -> Make Project来执行。
编译好了后,你会在你的项目module里面的build -> intermediates ->ndk ->发现对应的so文件。
注意你的项目所在的目录文件夹名字不能有空格,否则编译不通过了。
jnilib

上面的配置在运行时候,每次都会编译一下的,你程序有对应的调用代码会调用到这个文件的,如果你不想每次都编译一下so库,你也可以把对应的so库拿出来用。
把刚刚生成的so文件连同文件夹复制到项目的libs文件夹里面,当然了,你也可以放到项目的其他位置。
注意要连同上面的“armeabli”,“armeabi-v7a”,”x86”文件夹一起复制,系统调用时候会根据不同的芯片架构来调用不同的so库。
这放到libs文件夹里面
然后在app的build.gradle指引一下配置目录,并设置不自动ndk编译。

android {
  ......
    sourceSets.main {
        jniLibs.srcDir 'libs'//放so文件的目录
        jni.srcDirs = [] //disable automatic ndk-build call
    }
}

好了上面几步你已经生成对应的so库了,下面就是调用。

4)调用so库

先需要加载动态库,动态库的名称是编译时候在build.gradle设置的名称。
然后像普通的方法一样调用即可。

public class MainActivity extends AppCompatActivity {

    static {        // 加载动态库
        System.loadLibrary("TestJNI");
    }

    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.text_hello);
        Jni jni = new Jni();
        tv.setText(jni.say("Hello world. This message is from Jni."));

    }
}

app显示的jni

logcat显示的jni

源码下载地址:https://github.com/loongX/AndroidJniDemo/tree/master

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/loongago/article/details/51542225

Android视频《JNI》

本视频讲解了c语言的基础语法、Android studio下的JNI开发环境搭建、Java调c语言中的方法、c语言调用Java中的方法,以及JNI技术在美图秀秀、锅炉压力系统、问卷调查等项目中的实际应用。
  • 2016年10月28日 15:19

Android studio jni 入门helloworld

最近忙着面试 ,基本上每个面试官都会问一句 会不会jni?会不会ndk?像我这么厉害的c和c++,难道真的要荒废了吗,说了你会别人又不听,那么 我就得写个jni来试试了,说了这么多,要不是一本正经的胡...
  • salute_li
  • salute_li
  • 2016-09-08 11:15:06
  • 1326

android JNI开发之HelloWorld(eclipse+ndk_r9d)

android JNI开发之HelloWorld(eclipse+ndk_r9d)1.工具:(1)eclipse +adt+sdk。 (2)ndk_r9d。 (3)java(jdk 1.8....
  • lewes1103
  • lewes1103
  • 2016-08-04 17:45:35
  • 441

android jni demo--helloworld

  • 2016年04月14日 10:10
  • 340KB
  • 下载

android jni helloworld

  • 2016年03月04日 15:22
  • 2.42MB
  • 下载

Android Studio JNI 基础入门--Hello World

本文转自:http://blog.csdn.net/tuoguang/article/details/48141251 java运行过程: java源代码通过j...
  • liuxiangjia
  • liuxiangjia
  • 2015-12-09 11:38:48
  • 1180

Android jni的调用过程JNI_OnLoad(),利用Android NDK编写一个简单的HelloWorld

1、JNI简介JNI全称为Java Native Interface(JAVA本地调用)。从Java1.1开始,JNI成为java平台的一部分,它允许Java代码和其他语言写的代码(如C&amp;am...
  • u011652925
  • u011652925
  • 2017-09-20 17:51:24
  • 186

Android Studio中使用JNI 把初夜送给HelloWorld

AndroidStudio玩JNI,比在eclipse简单十倍左右。不需要那些繁琐的配置。NDK也可以直接下到 一、建项目 相比平时建项目,多勾选一个,如图:   代表包含 C++支...
  • hycfire
  • hycfire
  • 2017-03-02 14:51:32
  • 151

编译好的Android JNI HelloWorld

  • 2014年02月26日 21:36
  • 263KB
  • 下载

Android移植---JNI中HelloWorld的C和C++实现

MainActivity.java package com.example.jniload; import android.os.Bundle; import android.app.Activi...
  • yixuaning
  • yixuaning
  • 2014-01-28 09:14:36
  • 1908
收藏助手
不良信息举报
您举报文章:Android Jni之Helloworld
举报原因:
原因补充:

(最多只允许输入30个字)