• 基于 Android NDK 的学习之旅Java 调用C(附源码)


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

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

    我认为:

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

    2、  C的速度一般是java10-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(int x,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例子

     

    欢迎转载,请注明出处  http://www.cnblogs.com/luxiaofeng54/archive/2011/08/15/2139934.html


  • 相关阅读:
    000-ESP32学习开发(SDK)-ESP32开发板使用说明
    2-STM32 替换说明-CKS32, HK32, MM32, APM32, CH32, GD32, BLM32, AT32(推荐), N32, HC华大系列
    002-CH579M学习开发-官方资料学习说明,开发板蓝牙(蓝牙定位),网口通信测试
    001-CH579M学习开发-硬件使用说明,下载和运行第一个程序
    STM32+CH395Q(以太网)基本控制篇(自建物联网平台)-硬件使用说明
    17-网络芯片CH395Q学习开发-片内EEPROM读写实验
    16-网络芯片CH395Q学习开发-低功耗实验
    15-网络芯片CH395Q学习开发-DNS 域名解析
    14-1-网络芯片CH395Q学习开发-WEB服务器-网页到底是啥, web服务器是啥, 网页如何显示的显示图片和视频
    13-网络芯片CH395Q学习开发-模块使用Socket0作为MAC RAW
  • 原文地址:https://www.cnblogs.com/luxiaofeng54/p/2139934.html
Copyright © 2020-2023  润新知