基于 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
- 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);
- }
- }
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);
#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;
- }
#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);
- }
#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