Android JNI实现简单的c层调用Java层函数(C层调用Java层Toast进行提示)

简介: 终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~以前做过一段时间的JNI开发但是总是容易忘记一些简单的jni操作,最近重拾走过的jni开发之路,这里记录下如何在c层调用Java层类及方法,这里的类和方法可以是SDK里面的,也可以是自己编写的。

终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~

以前做过一段时间的JNI开发但是总是容易忘记一些简单的jni操作,最近重拾走过的jni开发之路,这里记录下如何在c层调用Java层类及方法,这里的类和方法可以是SDK里面的,也可以是自己编写的。这里分别给出测试工程,工程地址在文章末尾给出。JNI开发的环境配置及简单的JNI介绍百度一下资料很多。

首先编写MyTest.java类

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

/**
 * Created by hty on 2016/8/5.
 */
public class MyTest {

    static {
        System.loadLibrary("mytest");
    }

    private Context mContext;

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

    //调用自定义类的方法
    public native void callShow(String msg);
    //调用SDK里面的方法
    public native void callToastShow(Context context,String msg);
}
然后利用javah生成对应的头文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <android/log.h>
/* Header for class com_scu_jnidemo_MyTest */
#define TAG "mytest"
#define LOGE(...) __android_log_print(__ANDROID_LOG_ERROR,TAG,__VA_ARGS_)/*这里是LOGE日志*/

#ifndef _Included_com_scu_jnidemo_MyTest
#define _Included_com_scu_jnidemo_MyTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_scu_jnidemo_MyTest
 * Method:    callShow
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_scu_jnidemo_MyTest_callShow
  (JNIEnv *, jobject, jstring);

/*
 * Class:     com_scu_jnidemo_MyTest
 * Method:    callToastShow
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_scu_jnidemo_MyTest_callToastShow
  (JNIEnv *, jobject,jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif
最后编写对应的.cpp文件

//
// Created by hty on 2016/8/5.
//
#include "com_scu_jnidemo_MyTest.h"

/*
 * Class:     com_scu_jnidemo_MyTest
 * Method:    callShow
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_scu_jnidemo_MyTest_callShow
  (JNIEnv *env, jobject thiz, jstring str){
    jclass myclass = env->FindClass("com/scu/jnidemo/MyTest");
    jmethodID mid = env->GetMethodID(myclass,"show","(Ljava/lang/String;)V");
    env->CallVoidMethod(thiz,mid,str);
  }

/*
 * Class:     com_scu_jnidemo_MyTest
 * Method:    callToastShow
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_scu_jnidemo_MyTest_callToastShow
  (JNIEnv *env, jobject thiz,jobject context, jstring str){
     jclass tclss = env->FindClass("android/widget/Toast");
     jmethodID mid = env->GetStaticMethodID(tclss,"makeText","(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;");
     jobject job = env->CallStaticObjectMethod(tclss,mid,context,str);
     jmethodID showId = env->GetMethodID(tclss,"show","()V");
     env->CallVoidMethod(job,showId,context,str);
  }
最后在主程序里面进行测试:

package com.scu.jnidemo;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity implements View.OnClickListener{

    private TextView text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (TextView)findViewById(R.id.text);
        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        MyTest myTest = new MyTest(this);
        switch (view.getId()){
            case R.id.button1:
                myTest.callShow("这个是调用MyTest类里面的show");
                break;
            case R.id.button2:
                myTest.callToastShow(this,"这个是JNI直接调用Toast");
                break;
        }
    }
}
在程序里面需要注意的是在local.propreties里面需要将对应的sdk.dir和ndk.dir改成自己的路径

这里给出工程源码地址:JNI实现C层调用Java层函数

目录
相关文章
|
1月前
|
JavaScript 前端开发 Java
Java Script中的函数原型是什么
Java Script中的函数原型是什么
10 0
|
4月前
|
Java 开发工具 Android开发
OpenCV(一):Android studio jni配置OpenCV(亲测有效,保姆级)
OpenCV(一):Android studio jni配置OpenCV(亲测有效,保姆级)
156 0
|
23天前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
88 3
|
1月前
|
Android开发
[Android jni] Bitmap与Mat对象的相互转换
[Android jni] Bitmap与Mat对象的相互转换
46 0
|
3月前
|
Java
java的OutputStream.writeUTF()函数
java的OutputStream.writeUTF()函数
34 4
|
4月前
|
Java 开发工具 Android开发
[Android]JNI的基础知识
[Android]JNI的基础知识
40 0
[Android]JNI的基础知识
|
4月前
|
算法 Java 数据安全/隐私保护
Android App开发之利用JNI实现加密和解密操作实战(附源码 简单易懂)
Android App开发之利用JNI实现加密和解密操作实战(附源码 简单易懂)
67 0
|
4月前
|
XML Java API
Android App开发之创建JNI接口获取CPU指令集讲解及实战(附源码 简单易懂)
Android App开发之创建JNI接口获取CPU指令集讲解及实战(附源码 简单易懂)
39 0
|
4月前
|
Java 编译器 开发工具
Android StudioJNI开发之NDK环境的搭建以及添加JNI支持(图文解释 简单易懂)
Android StudioJNI开发之NDK环境的搭建以及添加JNI支持(图文解释 简单易懂)
30 0
|
4月前
|
算法 Java
给定一个字符串数组,如何找到其中最长的回文子串? 要求:编写一个Java函数,输入一个字符串数组,输出其中最长的回文子串。要求时间复杂度为O(n^2)。可以考虑使用动态规划或中心扩展的方法来优化算法。
给定一个字符串数组,如何找到其中最长的回文子串? 要求:编写一个Java函数,输入一个字符串数组,输出其中最长的回文子串。要求时间复杂度为O(n^2)。可以考虑使用动态规划或中心扩展的方法来优化算法。
41 1