Android 实战JNI之“hello world”

传统方式的具体流程

1.新建java NDKTools类
package gebilaolitou.ndkdemo;
public class NDKTools {
    public static native String getStringFromNDK();
}

在java当前目录下执行下面的命令javah -jni gebilaolitou.ndkdemo.NDKTools。如果没有问题,则会java当前目录生成gebilaolitou_ndkdemo_NDKTools.h文件
在这里插入图片描述

内容如下

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

#ifndef _Included_gebilaolitou_ndkdemo_NDKTools
#define _Included_gebilaolitou_ndkdemo_NDKTools
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     gebilaolitou_ndkdemo_NDKTools
 * Method:    getStringFromNDK
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_gebilaolitou_ndkdemo_NDKTools_getStringFromNDK
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

2.新建jni文件夹,把生成的gebilaolitou_ndkdemo_NDKTools.h文件放到这个目录下,并再新建2个文件,一个c文件ndkdemotest.c 和 Android.mk文件。

注意:此处的c文件也可以是cpp文件,看你是c代码还是c++代码。
在这里插入图片描述
ndkdemotest.c文件内容如下

#include "gebilaolitou_ndkdemo_NDKTools.h"

JNIEXPORT jstring JNICALL Java_gebilaolitou_ndkdemo_NDKTools_getStringFromNDK
  (JNIEnv *env, jobject obj){
     return (*env)->NewStringUTF(env,"Hellow World,这是隔壁老李头的NDK的第一行代码");
  }

Android.mk文件如下

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := ndkdemotest-jni

LOCAL_SRC_FILES := ndkdemotest.c

include $(BUILD_SHARED_LIBRARY)

3.检查local.properties文件中是否有NDK路径,如果有没有NDK路径,则添加NDK路径,比如我的如下:
ndk.dir=/Users/lijie/Library/Android/sdk/ndk-bundle
sdk.dir=/Users/lijie/Library/Android/sdk

其次修改app module目录下的build.gradle中的内容,如下:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "chn.fz.thatjay.scrolleditview"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        externalNativeBuild {
            ndkBuild {
                path 'src/main/jni/Android.mk'
            }
        }
        sourceSets.main {
            jni.srcDirs = []
            jniLibs.srcDirs = ['src/main/jniLibs']
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.gyf.immersionbar:immersionbar:2.3.3'
    implementation 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.orhanobut:logger:2.2.0'
    api 'com.yanzhenjie.permission:support:2.0.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

执行代码效果:

static {
    System.loadLibrary("ndkdemotest-jni");
}
private void test(){
    Log.d("hahaha", NDKTools.getStringFromNDK());
}

控制台输入打印:

Hellow World,这是隔壁老李头的NDK的第一行代码

4.传统方式的so文件

那so去哪里了,我们平时使用第三方的sdk的so的时候,会要粘贴复制到项目里面,而我们上所述整个过程,并没有出现.so这个文件,那么这个.so去哪里了?
其实Android Studio自动帮我们把so放到apk里面,如果我们想找也能找到,如下图:

注意:我用mac mumu模拟器运行,目前就x86文件夹有生成so文件,其他文件夹没有so文件。

本人电脑屏幕太小,分成两张图截。
在这里插入图片描述在这里插入图片描述


通过CMake工具demo演示流

1.CMake安装

在这里插入图片描述

2.新建项目,选择Native C++项目在这里插入图片描述

在这里插入图片描述

在Android Studio 完成新项目的创建后,请从IDE左侧打开Project 矿口并选择Android 视图。如下图所示,Android Studio 将添加cpp和External Build Files 组:

在这里插入图片描述

直接运行项目
我们来直接 run一下这个项目,看下结果

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_chn_fz_thatjay_myapplication_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

执行代码效果:

package chn.fz.thatjay.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }
    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

在这里插入图片描述


CMake工具demo的背后原理

我们看打了,我们什么都没做,就自动实现了C++的实现,它的背后原理是什么那?我们大家就思考一下?
CMake的入口

它既然可以跑起来,一定有一个入口,那这个入口在哪里那?
先和大家说下我是怎么想象的,首先我们在点击Android Studio中的run按钮的时候,它是执行Gradle来进行打包的,所以说关于CMake的是怎么植入进去的,一定在项目的build.gradle,有相应的入口。

参见文章https://www.jianshu.com/p/b4431ac22ec2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值