1. 程式人生 > >Android studio 配置NDK及開發例項

Android studio 配置NDK及開發例項

7. 編譯so庫檔案

此時,在Terminal視窗中執行ndk-build,就可以得到編譯的so檔案。

$ ndk-build
Android NDK: WARNING: APP_PLATFORM android-14 is higher than android:minSdkVersion 1 in ./AndroidManifest.xml. NDK binaries will *not* be comptible with devices older than android-14. See https://android.googlesource.com/platform/ndk/+/master/docs/user/common_problems.md for more information.    
[arm64-v8a] Compile : Factorial <= ai_nixie_aiden_factorialdemo_Factorial.c [arm64-v8a] SharedLibrary : libFactorial.so [arm64-v8a] Install : libFactorial.so => libs/arm64-v8a/libFactorial.so [x86_64] Compile : Factorial <= ai_nixie_aiden_factorialdemo_Factorial.c [x86_64] SharedLibrary : libFactorial.so [x86_64] Install : libFactorial.so => libs/x86_64/libFactorial.so [mips64] Compile : Factorial <= ai_nixie_aiden_factorialdemo_Factorial.c [mips64] SharedLibrary : libFactorial.so [mips64] Install : libFactorial.so => libs/mips64/libFactorial.so [armeabi-v7a] Compile thumb : Factorial <= ai_nixie_aiden_factorialdemo_Factorial.c [armeabi-v7a] SharedLibrary : libFactorial.so [armeabi-v7a] Install : libFactorial.so => libs/armeabi-v7a/libFactorial.so [armeabi] Compile thumb : Factorial <= ai_nixie_aiden_factorialdemo_Factorial.c [armeabi] SharedLibrary : libFactorial.so [armeabi] Install : libFactorial.so => libs/armeabi/libFactorial.so [x86] Compile : Factorial <= ai_nixie_aiden_factorialdemo_Factorial.c [x86] SharedLibrary : libFactorial.so [x86] Install : libFactorial.so => libs/x86/libFactorial.so [mips] Compile : Factorial <= ai_nixie_aiden_factorialdemo_Factorial.c [mips] SharedLibrary : libFactorial.so [mips] Install : libFactorial.so => libs/mips/libFactorial.so

配置根目錄下的 build.gradle 檔案

新增如下程式碼:    sourceSets{        main{               jni.srcDirs = [] // disable automatic ndk-build call, which ignore our Android.mk               jniLibs.srcDir 'src/main/libs'              }     }

8. 連結C++程式碼和Gradle

在編譯整個專案的時候可能會得到下面的錯誤。

8-1.png8-2.png

jni資料夾下的任意檔案上右擊,選擇Link C++ Project with Gradle

8-3.png

選擇ndk-build,並找到並選擇它的Android.mk檔案,然後OK。

8-4.png

執行完這一步後,在build.gradle檔案中android下面多了幾行:

externalNativeBuild {
    ndkBuild {
        path 'src/main/jni/Android.mk'
    }
}

其實直接在這個檔案中加入這幾行應該就可以了。

9. 匯入庫檔案

在Factorial.java檔案中,加入匯入庫檔案的程式碼,

static {
    System.loadLibrary("Factorial");
}

完成後如下:

package ai.nixie.aiden.factorialdemo;
public class Factorial {
    public static long fac(long n){
        return n <=0? 1 : n * fac(n-1);
    }
    public native static long facNTV(long n);
    static {
        System.loadLibrary("Factorial");
    }
}

好了,現在先測試一下,應該可以正常編譯了。不過我們現在還沒有在我們的APP中用上so庫的功能。

9-1.png9-2.png

10. 完善APP,驗證我們的so庫

10.1 修改佈局檔案

修改res/layout/activity_main.xml檔案,改為LinearLayout佈局,加入3個控制元件,一個輸入框用於輸入數字,一個文字框用於顯示結果,一個按鈕。

完成後如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <EditText
        android:id="@+id/input"
        android:text="5"
        android:textSize="32dp"
        android:textAlignment="center"
        android:selectAllOnFocus="true"
        android:inputType="text"
        android:maxLines="1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/result"
        android:textSize="32dp"
        android:textAlignment="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="result"
        />

    <Button
        android:id="@+id/calculate"
        android:text="Calculate"
        android:textSize="32dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

10.2 修改主java檔案MainActivity.java

主要的幾個修改點:

  • 加入implements監聽Click事件。
  • 獲得3個控制元件,併為按鈕加入Click事件監聽。
  • 在onClick函式中,實現點選時計算階乘的功能。其中用到了:
    • 判斷字串是否為空
    • String轉換成Long
  • 建立了Factorial的一個例項,並呼叫它的方法來實現階乘的功能。
  • 將階乘的計算結果,進行字串格式化後,顯示在文字框中。

修改完成的MainActivity.java檔案為:

package ai.nixie.aiden.factorialdemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private EditText inputBox;
    private TextView tvResult;
    private Button calButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        inputBox = (EditText) findViewById(R.id.input);
        tvResult = (TextView) findViewById(R.id.result);
        calButton = (Button) findViewById(R.id.calculate);

        calButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {

        String in = inputBox.getText().toString();

        if (TextUtils.isEmpty(in)) {
            return;
        }
        long input = Long.parseLong(in);

        /*  These two lines are the most important! */
        Factorial myFactorial = new Factorial();
        long result = myFactorial.facNTV(input);
        /*  These two lines are the most important! */

        tvResult.setText(String.format("fac(%d)=%d", input, result));

    }
}

其中最主要的是這2句:

Factorial myFactorial = new Factorial(); //生成一個Factorial類的例項,
long result = myFactorial.facNTV(input); //然後呼叫它的facNTV或fac方法,來計算階乘。

11. 編譯測試

到此專案完成。實際的執行結果圖:


11-1.png

完成後的專案樹: