JNI介绍(一)

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

  在工作中有用过JNI调用, 虽然实际项目中有用过,但是却从来没有去做知识的梳理。趁现在比较不忙,做下知识的梳理。

一、什么是JNI

    百度百科的解释:JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。

在工作中,有时候需要调用到C/C++的代码,比如第三方库FFmpeg,或者调用一些由C/C++写的方法,都需要用到JNI。

二、Android studio JNI开发方法

1.声明Native方法

package cn.zzw.jnidemo1.jni;

public class JniTools {
    public static native String getMessage(String name);
}

2.生成class文件

利用AS的Terminal,到文件所在的目录下,执行 javac JniTools.java ,生成class文件

3.通过javah生成头文件

这个必须是在app\src\main\java 目录下去执行 javah -jni cn.zzw.jnidemo1.jni.JniTools,这里是 javah -jni +包名+类名。

如果在其他目录下执行,例如如下两种错误:

在main目录下创建jni文件夹并将.h文件剪切到该文件夹

.h文件如下:

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

#ifndef _Included_cn_zzw_jnidemo1_jni_JniTools
#define _Included_cn_zzw_jnidemo1_jni_JniTools
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     cn_zzw_jnidemo1_jni_JniTools
 * Method:    getMessage
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_cn_zzw_jnidemo1_jni_JniTools_getMessage
  (JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

4.在jni目录下创建.c文件

//
// Created by zuowe on 2019/5/23.
//
#include "cn_zzw_jnidemo1_jni_JniTools.h"
JNIEXPORT jstring JNICALL Java_cn_zzw_jnidemo1_jni_JniTools_getMessage(JNIEnv *env, jclass jc, jstring jname)
{
  return (*env)->NewStringUTF(env,"I am from jni libs!");
}



5.在jni目录创建Android.mk和Application.mk

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := myjni

LOCAL_SRC_FILES := toolsfromc.c

include $(BUILD_SHARED_LIBRARY)

 Application.mk

APP_MODULES := myjni
APP_ABI := all

6.修改app下的build.gradle

        ndk{
            moduleName "myjni"
//            abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定的三种abi体系下的so库
        }
        sourceSets.main{
            jni.srcDirs = []
            jniLibs.srcDir "src/main/libs"
        }

7.在项目的gradle.properties中添加如下

android.useDeprecatedNdk=true

8.配置并执行ndk-build

配置:

执行:

在jni右键--》External Tools--》ndk-build

 结果:

生成如下.so文件

9.调用jni

10.显示结果:

 

11.上面的方式是Java调用C,再来个C调用Java的例子 

Java类:

package cn.zzw.jnidemo1.jni;

import android.content.Context;
import android.widget.Toast;

public class ToastTools {
    static {
        //加载本地库
        System.loadLibrary("myjni");
    }

    private Context mContext;

    public ToastTools(Context mContext) {
        this.mContext = mContext;
    }

    public void show(String msg) {
        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
    }

    public native void callToastShow(String msg);

}

12. C调用Java例子:c文件

#include "cn_zzw_jnidemo1_jni_ToastTools.h"
JNIEXPORT void JNICALL Java_cn_zzw_jnidemo1_jni_ToastTools_callToastShow
  (JNIEnv *env, jobject obj, jstring jmsg)
{
    jclass clazz  = (*env)->FindClass(env,"cn/zzw/jnidemo1/jni/ToastTools");
    jmethodID mid = (*env)->GetMethodID(env,clazz,"show","(Ljava/lang/String;)V");
    (*env)->CallVoidMethod(env, obj,mid,jmsg);
}

13.C调用Java例子:在Activity中调用

package cn.zzw.jnidemo1;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import cn.zzw.jnidemo1.jni.JniTools;
import cn.zzw.jnidemo1.jni.ToastTools;

public class MainActivity extends AppCompatActivity {

    public native void sendMsgToC(String msg);

    private TextView mTv;
    int i = 0;
    private Button mBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final ToastTools toastTools=new ToastTools(this);
        mTv = findViewById(R.id.mTv);
        mTv.setText(JniTools.getMessage("zzw"));
        mBtn = findViewById(R.id.mBtn);
        mBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                i++;
                toastTools.callToastShow("i am " + i);
            }
        });
    }

}

14. C调用Java例子:效果

源码下载:https://download.csdn.net/download/zzw0221/11202976

猜你喜欢

转载自blog.csdn.net/zzw0221/article/details/90311024
今日推荐