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

171 篇文章 0 订阅


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

随便谈谈为什么要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 

  1. package com.duicky;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. import android.widget.EditText;  
  10.   
  11. /** 
  12.  * Java 调用 C 例子  
  13.  *  
  14.  * @author luxiaofeng <454162034@qq.com> 
  15.  * 
  16.  */  
  17. public class MainActivity extends Activity {  
  18.     //也就是你mk配置文件中的  LOCAL_MODULE    := NDK_03  
  19.     private static final String libSoName = "NDK_03";  
  20.     private static final String tag = "MainActivity";  
  21.       
  22.     private Context mContext = null;  
  23.     private Button btnClick = null;  
  24.     private String mStrMSG = null;  
  25.     private EditText etX = null;  
  26.     private EditText etY = null;  
  27.     private EditText etResult = null;  
  28.       
  29.     private int x = 0 ;  
  30.     private int y = 0 ;  
  31.       
  32.       
  33.     /** Called when the activity is first created. */  
  34.     @Override  
  35.     public void onCreate(Bundle savedInstanceState) {  
  36.         super.onCreate(savedInstanceState);  
  37.         setContentView(R.layout.main);  
  38.           
  39.         mContext = this;  
  40.         //初始化控件  
  41.         initViews();  
  42.     }  
  43.       
  44.     /** 
  45.      * 初始化控件 
  46.      */  
  47.     private void initViews() {  
  48.         etX = (EditText)findViewById(R.id.et_x);  
  49.         etY = (EditText)findViewById(R.id.et_y);  
  50.         etResult = (EditText)findViewById(R.id.et_result);  
  51.         btnClick = (Button) findViewById(R.id.btn_click);  
  52.         btnClick.setOnClickListener(new OnClickListener() {  
  53.               
  54.             public void onClick(View v) {  
  55.   
  56.                 if(getX() && getY()){  
  57.                     int result = add(x,y);  
  58.                     LogUtils.printWithLogCat(tag,x+" + " + y + " = " +result);  
  59.                     etResult.setText(String.valueOf(result));  
  60.                 } else {  
  61.                     etX.setText("");  
  62.                     etY.setText("");  
  63.                     etResult.setText("");  
  64.                     LogUtils.toastMessage(mContext, "请输入正确的值");  
  65.                 }  
  66.                   
  67.             }  
  68.         });  
  69.           
  70.     }  
  71.   
  72.     /** 
  73.      * 获取x 
  74.      */  
  75.     private boolean getX() {  
  76.         String str = etX.getText().toString().trim();  
  77.         try {  
  78.             x = Integer.valueOf(str);  
  79.         } catch(NumberFormatException e) {  
  80.             return false;  
  81.         }  
  82.         return true;  
  83.     }  
  84.       
  85.     /** 
  86.      * 获取y 
  87.      */  
  88.     private boolean getY() {  
  89.         String str = etY.getText().toString().trim();  
  90.         try {  
  91.             y = Integer.valueOf(str);  
  92.         } catch(NumberFormatException e) {  
  93.             return false;  
  94.         }  
  95.         return true;  
  96.     }  
  97.       
  98.     /** 
  99.      * 该方法为native方法. 
  100.      *  
  101.      *      实现加法功能 
  102.      *  
  103.      * @param x 加数 
  104.      * @param y 加数 
  105.      *  
  106.      * @return x+y 的结果 
  107.      */  
  108.     public native int add(int x, int y);  
  109.       
  110.     /** 
  111.      * 载入JNI生成的so库文件 
  112.      */  
  113.     static {  
  114.         System.loadLibrary(libSoName);  
  115.     }  
  116.       
  117. }  
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

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

int add(int x, int y);


 

Operate.c

  1. #include"Operate.h"  
  2. /** 
  3.  * C 实现的加法 
  4.  */  
  5. int add(int x,int y) {  
  6. return x+y;  
  7. }  
#include"Operate.h"
/**
 * C 实现的加法
 */
int add(int x,int y) {
return x+y;
}


 

JavaToC.c

  1. #include <string.h>  
  2. #include <android/log.h>  
  3. #include <jni.h>  
  4. #include "Operate.h"  
  5.   
  6.   
  7. /** 
  8.  *  Java 中 声明的native add 方法的实现 
  9.  * 
  10.  *      jint x  参数X 
  11.  *      jint y  参数Y 
  12.  */  
  13. jint Java_com_duicky_MainActivity_add(JNIEnv* env, jobject thiz,  
  14.         jint x,jint y)  
  15. {  
  16.   
  17.     //该方法为打印的方法  
  18.     __android_log_print(ANDROID_LOG_INFO, "JNIMsg""Get Param:  x=%d y=%d ", x,y);  
  19.   
  20.     return add(x,y);  
  21. }  
#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://blog.csdn.net/dui_cky/article/details/6690042

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值