讀古今文學網 > Android程序設計:第2版 > 編譯自己定制的庫模塊 >

編譯自己定制的庫模塊

本節把貫穿本章的幾種技術綜合在了一起,創建和使用簡單的C模塊,它使用math庫來計算冪值。我們將從文件Android.mk開始。注意,需要構建庫(sample_lib),並輸出include文件,然後在示例中使用這個庫:


LOCAL_PATH := $(call my-dir)
  # this is our sample library
include $(CLEAR_VARS)
LOCAL_MODULE    := sample_lib
LOCAL_SRC_FILES := samplelib/sample_lib.c
  # we need to make sure everything knows where everything is
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/samplelib
include $(BUILD_STATIC_LIBRARY)
  # sample uses the sample lib we created
include $(CLEAR_VARS)
LOCAL_MODULE    := sample
LOCAL_SRC_FILES := sample.c
LOCAL_LDLIBS    := -llog
  # We load our sample lib
LOCAL_STATIC_LIBRARIES := sample_lib
include $(BUILD_SHARED_LIBRARY)
有一個短頭文件sample_lib.h
:
#ifndef SAMPLE_LIB_H
#define SAMPLE_LIB_H
extern double calculatePower(double x, double y);
#endif
  

函數sample_lib.c的源代碼如下所示:


#include \"sample_lib.h\"
   // we include the math lib
#include \"math.h\"
  // we use the math lib
double calculatePower(double x, double y) {
    return pow(x, y);
}
  

以下sample.c文件把sample_lib庫和Java代碼結合起來:


  // we include the sample_lib
#include \"sample_lib.h\"
#include <jni.h>
#include <android/log.h>
#define LOGINFO(x...) __android_log_print(ANDROID_LOG_INFO,\"SampleJNI\",x)
jdouble
  Java_com_oreilly_demo_android_pa_ndkdemo_SampleActivityWithNativeMethods_calculatePower(
                        JNIEnv* env, jobject thisobject, jdouble x, jdouble y) {
    LOGINFO(\"Sample Info Log Output\");
    // we call sample-lib\'s calculate method
    return calculatePower(x, y);
}
  

本例Activity所使用的佈局如下所示:


<?xml version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
    android:orientation=\"vertical\"
    android:layout_
    android:layout_
      >
<EditText
    android:id=\"@+id/x\"
    android:layout_
    android:layout_
    android:paddingTop=\"5dp\"
    android:paddingBottom=\"5dp\"
    android:textColor=\"#000\"
    android:hint=\"X Value\"
    />
<EditText
    android:id=\"@+id/y\"
    android:layout_
    android:layout_
    android:paddingTop=\"5dp\"
    android:paddingBottom=\"5dp\"
    android:textColor=\"#000\"
    android:hint=\"Y Value\"
    />
<Button
    android:id=\"@+id/calculate\"
    android:layout_
    android:layout_
    android:paddingTop=\"5dp\"
    android:paddingBottom=\"5dp\"
    android:text=\"Calculate X^Y\"
    />
</LinearLayout>
  

接下來我們修改的SampleActivityWithNativeMethods activity,它使用了新的庫文件,加載該示例庫並聲明calculatePower方法。當單擊calculate按鈕時,接收兩個編輯文本框中獲取的數值(如果文本為空或不是數值形式,默認使用2),並把這兩個數值傳遞給calculatePower方法。然後,返回的double類型的計算結果會彈出,作為Toast的一部分:


package com.oreilly.demo.android.pa.ndkdemo;
import com.oreilly.demo.android.pa.ndkdemo.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class SampleActivityWithNativeMethods extends Activity {
    static {
        System.loadLibrary(\"sample\"); // load our sample lib
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sample);
        setupview;
    }
    // sample lib native method
    public native double calculatePower(double x, double y);
    private void setupview {
        findViewById(R.id.calculate).setOnClickListener(
                                                new View.OnClickListener {
            public void onClick(View v) {
                String answer = \"\";
                double x = 2;
                double y = 2;
                String sx = ((EditText) findViewById(R.id.x)).getText.toString;
                String sy = ((EditText) findViewById(R.id.y)).getText.toString;
                if(sx == null) {
                    answer = \"X defaults to 2n\";
                } else {
                    try {
                        x = Double.parseDouble(sx);
                    } catch (Exception e) {
                        answer = \"X is not a number, defaulting to 2n\";
                        x = 2;
                    }
                }
                if(sy == null) {
                    answer += \"Y defaults to 2n\";
                } else {
                    try {
                        y = Double.parseDouble(sy);
                    } catch (Exception e) {
                        answer = \"Y is not a number, defaulting to 2n\";
                        y = 2;
                    }
                }
                double z = calculatePower(x, y);
                answer += x+\"^\"+y+\" = \"+z;
                Toast.makeText(SampleActivityWithNativeMethods.this, answer,
                                                        Toast.LENGTH_SHORT).show;
            }
        });
    }
}