天天看點

基于 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(int x,int y),并把結果傳回

d)      Android 上層顯示結果

2、設計實作

       1、界面設計如下:

基于 Android NDK 的學習之旅-----Java 調用C

比較搓一點,大家别見笑(嘎嘎),代碼不貼了,兄弟們可以直接下載下傳整個工程

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 <[email protected]>
 *
 */
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方法得出結果

基于 Android NDK 的學習之旅-----Java 調用C

  JNI層擷取到參數列印出來

基于 Android NDK 的學習之旅-----Java 調用C

本章節隻做簡單Java 調用 C 入門介紹 , 以後的一些文章 會詳細說明 Java JNI C 層之間的資料傳輸問題。

你懂了嗎? 無論你懂不懂,反正我是懂了(嘎嘎,太邪惡了)

有不了解的兄弟請留言,個人技術有限,有講錯的地方請大牛們指出,講的不夠全面的請多多包涵,謝謝,

點選下載下傳源碼 java調用C例子

歡迎轉載,請注明出處  http://www.cnblogs.com/luxiaofeng54/archive/2011/08/15/2139934.html