美文网首页Android开发Android技术知识Android开发
基于 Android NDK 的学习之旅-----Java 调用

基于 Android NDK 的学习之旅-----Java 调用

作者: Android高级架构探索 | 来源:发表于2019-02-19 14:58 被阅读4次

    原文链接: http://blog.csdn.net/dui_cky/article/details/6690042

    随便谈谈为什么要Java调用C 吧:

    我认为:

    1、 有些公司开发Android项目的时候, 许多组件功能可能是C中已经实现了,所以我们没必要同样的功能又在java中实现一遍。例如我之前做的一个项目,公司C引擎已经很成熟了,所以直接在java中封装好接口,由C去实现。

    2、 C的速度一般是java的10-20倍把,有些对速度要求高的就需要在C中实现。例如我以前在Android项目中有要求批量(10000++)生成MD5的值,由于测试对java中直接生成的效果不满意,所以后面就换成C去实现了。

    3、 …..

    不罗嗦了,直接开始吧。

    1、主要流程
    a) Java声明本地接口 add(int x, int y)

    b) C 中 实现 add(int x,int y)

    c) JNI中 java方法调用C 中的 add(intx,int y),并把结果返回

    d) Android 上层显示结果

    2、设计实现
    1、界面设计如下:

    比较搓一点,大家别见笑(嘎嘎),代码不贴了,兄弟们可以直接下载整个工程

    2、 Android 上层关键代码

    public native int add(int x, int y);

    该方法就是 要让 C 实现的本地方法。

    MainActivity.java

    package com.duicky;
    
    import android.app.Activity;
    import android.content.Context;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    
    /**
     * Java 调用 C 例子 
     * 
     * @author luxiaofeng <454162034@qq.com>
     *
     */
    public class MainActivity extends Activity {
        //也就是你mk配置文件中的  LOCAL_MODULE    := NDK_03
        private static final String libSoName = "NDK_03";
        private static final String tag = "MainActivity";
    
        private Context mContext = null;
        private Button btnClick = null;
        private String mStrMSG = null;
        private EditText etX = null;
        private EditText etY = null;
        private EditText etResult = null;
    
        private int x = 0 ;
        private int y = 0 ;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            mContext = this;
            //初始化控件
            initViews();
        }
    
        /**
         * 初始化控件
         */
        private void initViews() {
            etX = (EditText)findViewById(R.id.et_x);
            etY = (EditText)findViewById(R.id.et_y);
            etResult = (EditText)findViewById(R.id.et_result);
            btnClick = (Button) findViewById(R.id.btn_click);
            btnClick.setOnClickListener(new OnClickListener() {
    
                public void onClick(View v) {
    
                    if(getX() && getY()){
                        int result = add(x,y);
                        LogUtils.printWithLogCat(tag,x+" + " + y + " = " +result);
                        etResult.setText(String.valueOf(result));
                    } else {
                        etX.setText("");
                        etY.setText("");
                        etResult.setText("");
                        LogUtils.toastMessage(mContext, "请输入正确的值");
                    }
    
                }
            });
    
        }
    
        /**
         * 获取x
         */
        private boolean getX() {
            String str = etX.getText().toString().trim();
            try {
                x = Integer.valueOf(str);
            } catch(NumberFormatException e) {
                return false;
            }
            return true;
        }
    
        /**
         * 获取y
         */
        private boolean getY() {
            String str = etY.getText().toString().trim();
            try {
                y = Integer.valueOf(str);
            } catch(NumberFormatException e) {
                return false;
            }
            return true;
        }
    
        /**
         * 该方法为native方法.
         * 
         *      实现加法功能
         * 
         * @param x 加数
         * @param y 加数
         * 
         * @return x+y 的结果
         */
        public native int add(int x, int y);
    
        /**
         * 载入JNI生成的so库文件
         */
        static {
            System.loadLibrary(libSoName);
        }
    
    }
    
    


    3、 Android.mk 文件 关键代码

    LOCAL_MODULE := NDK_03

    LOCAL_SRC_FILES := \

    JavaToC.c \

    Operate.c

    不说了,你懂的。如果不懂,嘎嘎,那就请点击Android.mk文件 简介

    4、 JNI文件夹下文件

    Operate.h

    #include <string.h>
    #include <jni.h>
    
    int add(int x, int y);
    

    Operate.c

    #include"Operate.h"
    /**
     * C 实现的加法
     */
    int add(int x,int y) {
    return x+y;
    }
    
    

    JavaToC.c

    #include <string.h>
    #include <android/log.h>
    #include <jni.h>
    #include "Operate.h"
    
    /**
     *  Java 中 声明的native add 方法的实现
     *
     *      jint x  参数X
     *      jint y  参数Y
     */
    jint Java_com_duicky_MainActivity_add(JNIEnv* env, jobject thiz,
            jint x,jint y)
    {
    
        //该方法为打印的方法
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Get Param:  x=%d y=%d ", x,y);
    
        return add(x,y);
    }
    
    

    3、运行效果

    输入两个数字,调用C方法得出结果

    JNI层获取到参数打印出来

    本章节只做简单Java 调用 C 入门介绍 , 以后的一些文章 会详细说明 Java JNI C 层之间的数据传输问题。

    你懂了吗? 无论你懂不懂,反正我是懂了(嘎嘎,太邪恶了)

    有不理解的兄弟请留言,个人技术有限,有讲错的地方请大牛们指出,讲的不够全面的请多多包涵,谢谢,

    点击下载源码java调用C例子

    最后给大家分享一份非常系统和全面的Android进阶技术大纲已经进阶资料

    想学习更多Android知识,或者获取相关资料请加入Android技术开发交流 878873098 进 群 即可找 群 管理免费领取

    主要是针对做移动开发一到五年,想系统深入提升或者是困于瓶颈的小伙伴。

    Android高级技术大纲,以及系统进阶视频;

    Android高级技术大纲 Android 进阶视频资料

    相关文章

      网友评论

        本文标题:基于 Android NDK 的学习之旅-----Java 调用

        本文链接:https://www.haomeiwen.com/subject/lhxfyqtx.html