學(xué)習(xí)JNI編程第2篇--導(dǎo)入/調(diào)用第三方so庫

軟硬件環(huán)境
MacBook Pro, OS X El Capitan, 10.11.6
Android Studio v2.3

2017.11.1更新:
本代碼已經(jīng)整理上傳到github.com,代碼后來更新過,所以內(nèi)容跟本文有出入。
鏈接:https://github.com/YigangFang/FactorialDemo

實際工作中,我們常常會拿到?jīng)]有源碼的第三方so庫,使用它們進行APP開發(fā)。

【學(xué)習(xí)JNI編程 第一篇】中,我們成功地編譯出了一個計算階乘的so庫。在本篇中,我們要使用這個so庫,假設(shè)在沒有源碼的情況下,開發(fā)一個APP。

1. 新建一個Android Studio項目

給項目命名,其它設(shè)置都保持默認即可。

項目創(chuàng)建好以后,設(shè)置視圖為Project。

2. 把得到的so庫復(fù)制到項目的libs目錄下

我們實際從第三方得到的so庫可能是針對多個平臺的,無論如何,把需要的庫復(fù)制到libs下面即可。

注意目錄結(jié)構(gòu):

3. 編寫jni文件

除了此項目默認生成的MainActivity以外,我們新建一個package包,包名是ai.nixie.aiden.factorialdemo.Factorial,嚴格跟so庫的一致。

在里面加了一行native的聲明,F(xiàn)actorial.java的全部內(nèi)容如下:

package ai.nixie.aiden.factorialdemo;

/**
 * Created by Aiden Fang on 8/10/17.
 */

public class Factorial {

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

    public static native long facNTV(long n);

}

注意:
這里loadLibrary進來的庫,是不包括lib前綴和.so后綴的。

4. 指定庫文件所在目錄

在build.gradle里的Android{}下,加入這樣一段。

sourceSets {
    main {
        jniLibs.srcDirs = ['src/main/libs']
    }
}

注意,src/main/libs要根據(jù)你的庫文件的實際存放目錄進行相應(yīng)修改。

5. 在MainActivity里,調(diào)用so庫定義的函數(shù)

內(nèi)容如下

package ai.nixie.aiden.sodemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import static ai.nixie.aiden.factorialdemo.Factorial.facNTV;

public class MainActivity extends AppCompatActivity {

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

        TextView tv = (TextView) findViewById(R.id.tvRes);
        tv.setText(String.format("fac(6) = %d", facNTV(6)));
    }
}

其實就2個地方,一是import庫函數(shù)那一行,二是調(diào)用facNTV函數(shù)。

6. 布局Layout文件 activity_main.xml

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

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

</LinearLayout>

7. 成功!

最終的項目樹

說明

  1. 因為我們得到的是已經(jīng)編譯好的so庫,所以build.gradle中不再需要ndk段落。
  2. 當(dāng)java層加載so庫時,因為是靜態(tài)注冊,所以需要在Factorial.java這個類中用loadLibrary來加載庫。
  3. 在build.gradle中的jniLibs的路徑是從build.gradle這個文件所在的目錄開始計算的,所以要注意跟so庫文件實際存放目錄匹配。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • demo鏈接在文末。 在Android Studio中有3種方法生成so文件。 最初的時候,我曾經(jīng)使用過Visua...
    梧葉已秋聲閱讀 34,250評論 5 26
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,323評論 25 708
  • 一.簽發(fā)證書 TLS雙向認知需要預(yù)先自建CA簽發(fā)證書,權(quán)威CA機構(gòu)的證書應(yīng)該不可用,因為大部分k8s都是在內(nèi)網(wǎng)中部...
    秋幻旎蘇閱讀 12,363評論 4 6
  • 《養(yǎng)魚的人》 作者:云羽落 我每天只做三件事,吃飯、睡覺和養(yǎng)魚。 我喜歡坐在樹下看著魚在封閉的生態(tài)魚缸中游動來消遣...
    云羽落閱讀 709評論 0 2
  • 記不平凡的一天。一個月兩次的值班今天輪到我了,還在一天比較閑重點是晚上沒有晚自習(xí)。打算著要忙完家長會的事,計...
    橙子糖屋閱讀 317評論 0 0

友情鏈接更多精彩內(nèi)容