Android Studio 2.3.3 圖解配置NDK開(kāi)發(fā)環(huán)境以及Hello Word To jni~

LZ-Says:半夜睡覺(jué)滾了地上了,無(wú)奈之下醒來(lái)了,想想最近幾天因?yàn)橐粋€(gè)括號(hào)導(dǎo)致JNI遲遲不能開(kāi)展,心里面無(wú)奈又崩潰,索性直接起來(lái)整完得了~

前言

當(dāng)前畢業(yè)的時(shí)候,感覺(jué)自己掌握了全世界,隨著參加工作的時(shí)間一天天的增長(zhǎng),突然覺(jué)得丫的,啥都不會(huì)啊,要學(xué)的東西還是太多太多了。不過(guò)近來(lái)被飛大姐洗腦成功,<font color=#FF0000>萬(wàn)事不過(guò)幾行代碼而已,干它~

So 今天為大家?guī)?lái)簡(jiǎn)單的jni配置,使用,以及運(yùn)行我們的第一個(gè)簡(jiǎn)單小demo`

Hi Jni

總是再說(shuō)jni,jni,那么jni到底是什么東西,我們一起來(lái)看看:

JNI是Java Native Interface的縮寫(xiě),它提供了若干的API實(shí)現(xiàn)了Java和其他語(yǔ)言的通信(主要是C&C++)。從Java1.1開(kāi)始,JNI標(biāo)準(zhǔn)成為java平臺(tái)的一部分,它允許Java代碼和其他語(yǔ)言寫(xiě)的代碼進(jìn)行交互。

JNI標(biāo)準(zhǔn)至少要保證本地代碼能工作在任何Java 虛擬機(jī)環(huán)境。

下面為大家附上官方Android平臺(tái)架構(gòu)圖:

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

可以看到Android上層的Application和ApplicationFramework都是使用Java編寫(xiě),底層包括系統(tǒng)和使用眾多的Libraries都是C/C++編寫(xiě)的,所以上層Java要調(diào)用底層的C/C++函數(shù)庫(kù)必須通過(guò)Java的JNI來(lái)實(shí)現(xiàn)。

Jni使用場(chǎng)景

當(dāng)你開(kāi)始著手準(zhǔn)備一個(gè)使用JNI的項(xiàng)目時(shí),請(qǐng)確認(rèn)是否還有替代方案。應(yīng)用程序使用JNI會(huì)帶來(lái)一些副作用。下面給出幾個(gè)方案,可以避免使用JNI的時(shí)候,達(dá)到與本地代碼進(jìn)行交互的效果:

1、JAVA程序和本地程序使用TCP/IP或者IPC進(jìn)行交互。
2、當(dāng)用JAVA程序連接本地?cái)?shù)據(jù)庫(kù)時(shí),使用JDBC提供的API。
3、JAVA程序可以使用分布式對(duì)象技術(shù),如JAVA IDL API。

這些方案的共同點(diǎn)是,JAVA和C處于不同的線程,或者不同的機(jī)器上。這樣,當(dāng)本地程序崩潰時(shí),不會(huì)影響到JAVA程序。

下面這些場(chǎng)合中,同一進(jìn)程內(nèi)JNI的使用無(wú)法避免:

1、程序當(dāng)中用到了JAVA API不提供的特殊系統(tǒng)環(huán)境才會(huì)有的特征。而跨進(jìn)程操作又不現(xiàn)實(shí)。
2、你可能想訪問(wèn)一些己有的本地庫(kù),但又不想付出跨進(jìn)程調(diào)用時(shí)的代價(jià),如效率,內(nèi)存,數(shù)據(jù)傳遞方面。
3、JAVA程序當(dāng)中的一部分代碼對(duì)效率要求非常高,如算法計(jì)算,圖形渲染等。

<font color=#FF0000>總之,只有當(dāng)你必須在同一進(jìn)程中調(diào)用本地代碼時(shí),再使用JNI。

Jni缺陷

一旦使用JNI,JAVA程序就喪失了JAVA平臺(tái)的兩個(gè)優(yōu)點(diǎn):

1、程序不再跨平臺(tái)。要想跨平臺(tái),必須在不同的系統(tǒng)環(huán)境下重新編譯本地語(yǔ)言部分。
2、程序不再是絕對(duì)安全的,本地代碼的不當(dāng)使用可能導(dǎo)致整個(gè)程序崩潰。一個(gè)通用規(guī)則是,你應(yīng)該讓本地方法集中在少數(shù)幾個(gè)類當(dāng)中。這樣就降低了JAVA和C之間的耦合性

Jni作用

JNI可以這樣與本地程序進(jìn)行交互:

1、你可以使用JNI來(lái)實(shí)現(xiàn)“本地方法”(native methods),并在JAVA程序中調(diào)用它們。

2、JNI支持一個(gè)“調(diào)用接口”(invocation interface),它允許你把一個(gè)JVM嵌入到本地程序中。本地程序可以鏈接一個(gè)實(shí)現(xiàn)了JVM的本地庫(kù),然后使用“調(diào)用接口”執(zhí)行JAVA語(yǔ)言編寫(xiě)的軟件模塊。

簡(jiǎn)單了解以上內(nèi)容后,我們開(kāi)啟正題,在Android開(kāi)發(fā)中,我們?cè)撛趺词褂胘ni,或者說(shuō)是在Android Studio中,我們?cè)撛趺词褂胘ni呢?表急,往下瞅瞅~

話說(shuō),我們開(kāi)發(fā)android應(yīng)用程序基礎(chǔ)不就是下載官方相關(guān)的SDK,ADT啥啥啥的,同理jni也一樣。

現(xiàn)在為大家簡(jiǎn)單介紹NDK~如下。

Hi NDK

Android NDK 是一套允許使用原生代碼語(yǔ)言(例如 C 和 C++)實(shí)現(xiàn)部分應(yīng)用的工具集。在開(kāi)發(fā)某些類型應(yīng)用時(shí),這有助于重復(fù)使用以這些語(yǔ)言編寫(xiě)的代碼庫(kù)。

同理,官方也為我們提供了一個(gè)小例子,簡(jiǎn)單走馬觀花看一下:

public class MyActivity extends Activity {
  /**
  * 使用 C/C++ 語(yǔ)言實(shí)現(xiàn)的原生方法
  */
  public native void computeFoo();
}

native方法,當(dāng)年看到這個(gè)東西感覺(jué)好高大上,沒(méi)想到而今我也能玩玩,哈哈,GGG~

官方對(duì)于NDK是這樣說(shuō)的:

NDK 不適用于大多數(shù)初學(xué)的 Android 編程者,對(duì)許多類型的 Android 應(yīng)用沒(méi)什么價(jià)值。 因?yàn)樗豢杀苊獾貢?huì)增加開(kāi)發(fā)過(guò)程的復(fù)雜性,所以通常不值得使用。 但如果您需要執(zhí)行以下操作,它可能很有用:

  • 從設(shè)備獲取卓越性能以用于計(jì)算密集型應(yīng)用,例如游戲或物理模擬;

  • 重復(fù)使用您自己或其他開(kāi)發(fā)者的 C 或 C++ 庫(kù)。

丫的,爺兒們好奇瞅瞅不行啊?

行~!

哈哈~

簡(jiǎn)單有個(gè)印象后,我們開(kāi)始配置相關(guān)內(nèi)容,為什么要說(shuō)這個(gè)配置呢,主要有以下幾個(gè)原因:

  • 雖說(shuō)配置是傻瓜式無(wú)腦操作,但是對(duì)于LZ小白這樣的人來(lái)說(shuō),依然覺(jué)得是一件很高大上的事兒,何況,丫的,連配置都不會(huì),還開(kāi)發(fā)個(gè)卵子?

  • 凡事兒親歷親為,不經(jīng)歷,怎能有成長(zhǎng)?

配置之前,我們還需要了解我們需要配置or下載哪兒些工具,以及這些東西都是干嘛的,不然稀里糊涂的,糟心。

同理,我們也需要去簡(jiǎn)單了解下使用NDK好處:

1、代碼的保護(hù)。由于apk的java層代碼很容易被反編譯,而C/C++庫(kù)反匯難度較大;
2、可以方便地使用現(xiàn)存的開(kāi)源庫(kù)。大部分現(xiàn)存的開(kāi)源庫(kù)都是用C/C++代碼編寫(xiě)的;
3、提高程序的執(zhí)行效率。將要求高性能的應(yīng)用邏輯使用C開(kāi)發(fā),從而提高應(yīng)用程序的執(zhí)行效率;
4、便于移植。用C/C++寫(xiě)得庫(kù)可以方便在其他的嵌入式平臺(tái)上再次使用。

NDK以及所需構(gòu)建工具簡(jiǎn)介

  • NDK:這個(gè)還需要再說(shuō)嘛?

  • CMake:外部構(gòu)建工具;

CMake是一個(gè)開(kāi)源的跨平臺(tái)系列工具,旨在構(gòu)建,測(cè)試和打包軟件。

CMake用于使用簡(jiǎn)單的平臺(tái)和編譯器獨(dú)立的配置文件來(lái)控制軟件編譯過(guò)程,并生成可以在選擇的編譯環(huán)境中使用的本地makefile和工作空間。

CMack工具套件由Kitware創(chuàng)建,以響應(yīng)對(duì)開(kāi)源項(xiàng)目(如ITK和VTK)的強(qiáng)大的跨平臺(tái)構(gòu)建環(huán)境的需求。

官方地址:https://cmake.org/ 有興趣可以簡(jiǎn)單了解下~

  • LLDB:Android Studio 上面調(diào)試本地代碼的工具

LLDB是下一代高性能調(diào)試器。它被構(gòu)建為一組可重用的組件,可以高度利用較大的LLVM項(xiàng)目中的現(xiàn)有庫(kù),例如Clang表達(dá)式解析器和LLVM反匯編程序。

在Mac OS X中,LLDB是Xcode中的默認(rèn)調(diào)試器,支持在桌面和iOS設(shè)備和模擬器上調(diào)試C,Objective-C和C ++。

LLDB項(xiàng)目中的所有代碼都可以使用標(biāo)準(zhǔn)的 LLVM許可證(一種開(kāi)放源代碼“BSD風(fēng)格”)許可證。

LLDB目前將調(diào)試信息轉(zhuǎn)換成clang類型,以便它可以利用clang編譯器基礎(chǔ)架構(gòu)。這允許LLDB在表達(dá)式中支持最新的C,C++,Objective C和Objective C ++語(yǔ)言特性和運(yùn)行時(shí)間,而無(wú)需重新實(shí)現(xiàn)任何此功能。在編寫(xiě)表達(dá)式的函數(shù),拆卸指令和提取指令詳細(xì)信息等時(shí),還可以利用編譯器來(lái)處理所有ABI細(xì)節(jié)。

主要優(yōu)點(diǎn)包括:

  1. C,C ++,Objective C的最新語(yǔ)言支持 ;
  2. 可以聲明局部變量和類型的多行表達(dá)式;
  3. 支持時(shí)使用JIT表達(dá)式;
  4. 當(dāng)JIT不能使用時(shí),評(píng)估表達(dá)式中間表示(IR)

官方地址:http://lldb.llvm.org/

以上簡(jiǎn)單了解下就好了,至于為啥要這么搞,就是為了方便以后有需要直接翻出來(lái)看看~

NDK配置(包含構(gòu)建工具,調(diào)試工具)

<font color=#FF0000>下載安裝NDK,有倆種方式,其實(shí)都一樣,只是一個(gè)需要手動(dòng)下載,解壓,配置目錄,一個(gè)Android Studio自動(dòng)完成以上操作。

配置NDK倆種方式

手動(dòng)下載NDK

NDK下載地址如下:

https://developer.android.google.cn/ndk/downloads/index.html

大家可自行選擇相應(yīng)版本進(jìn)行下載。

下載完成后,解壓本地目錄,在Android Studio中配置路徑即可,如下圖所示:

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

強(qiáng)大的Android Studio走起~

1.點(diǎn)擊Project Structure,選擇 Download Android NDK;

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

2.耐心等待吧,LZ下載比較快,解壓比較慢~

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

3.下載解壓完成,自動(dòng)錄入地址,省事兒哈~

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

到此,關(guān)于NDK下載安裝倆種方式圖解完畢~

我們看一下ndk目錄各個(gè)作用,簡(jiǎn)單了解下。

  • docs: 幫助文檔
  •       build/tools:linux的批處理文件
    
  •       platforms:編譯c代碼需要使用的頭文件和類庫(kù)
    
  •       prebuilt:預(yù)編譯使用的二進(jìn)制可執(zhí)行文件
    
  •      sample:jni的使用例子
    
  •      source:ndk的源碼
    
  •      toolchains:工具鏈
    
  •     ndk-build.cmd:編譯打包c(diǎn)代碼的一個(gè)指令,需要配置系統(tǒng)環(huán)境變量
    

配置構(gòu)建工具以及調(diào)試工具

1.如下圖所示,點(diǎn)擊SDK Manager,選擇下載安裝CMake以及LLDB;

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

簡(jiǎn)單看一下版本信息,果斷OK~

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

沒(méi)啥可說(shuō)的,等待,不過(guò)分分鐘搞定~

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

到此,基本配置已完成,但是如何查驗(yàn)NDK是否成功安裝了呢?

配置下環(huán)境變量瞅瞅唄~

配置環(huán)境變量

復(fù)制NDK地址,按如下圖示進(jìn)行操作即可。

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

cmd直接輸入ndk-build回車

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

在這里吐槽下LZ之前遇到的坑。

LZ目錄習(xí)慣命名為HLQWorkSofe(Android) or HLQWorkSofe(Java),在之前從來(lái)沒(méi)有出現(xiàn)過(guò)問(wèn)題,但是在NDK時(shí)候,卻怎么也不行,最后無(wú)奈下只能把()去掉。

問(wèn)題截圖如下:

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

<font color=#FF0000>搞得LZ都快放棄了,最后一試,好了,給我郁悶的,大家注意啊~

創(chuàng)建個(gè)項(xiàng)目玩一玩

創(chuàng)建項(xiàng)目時(shí),記得勾選下面的Include C++ support哦~

導(dǎo)入C++支持庫(kù),不然沒(méi)法玩哈~
<center>

這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

一路next下之后,關(guān)于最后一步選擇時(shí),在此作特殊說(shuō)明下。

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述
  • C++ Standard:使用下拉列表選擇您希望使用哪種 C++ 標(biāo)準(zhǔn)。選擇 Toolchain Default 會(huì)使用默認(rèn)的 CMake 設(shè)置;

  • Exceptions Support:如果您希望啟用對(duì) C++ 異常處理的支持,請(qǐng)選中此復(fù)選框。如果啟用此復(fù)選框,Android Studio 會(huì)將 -fexceptions 標(biāo)志添加到模塊級(jí) build.gradle 文件的 cppFlags 中,Gradle 會(huì)將其傳遞到 CMake;

  • Runtime Type Information Support:如果您希望支持 RTTI,請(qǐng)選中此復(fù)選框。如果啟用此復(fù)選框,Android Studio 會(huì)將 -frtti 標(biāo)志添加到模塊級(jí) build.gradle 文件的 cppFlags 中,Gradle 會(huì)將其傳遞到 CMake。

點(diǎn)擊Finish之后,我們稍等片刻~

查看默認(rèn)生成例子

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

下面我們一起來(lái)探究下官方提供的例子,看看從例子中我們能得知什么對(duì)我們有用的信息。

從上圖可看到,和以前唯一不同的就是多出了cpp目錄以及External Build Files倆個(gè)目錄,那么這倆個(gè)都有什么用呢?一起來(lái)看看。

  • cpp 目錄存放所有 native code 的地方,包括源碼,頭文件,預(yù)編譯項(xiàng)目等。對(duì)于新項(xiàng)目,Android Studio 創(chuàng)建了一個(gè) C++ 模板文件:native-lib.cpp,并且將該文件放到了你的 app 模塊的 src/main/cpp/ 目錄下。這份模板代碼提供了一個(gè)簡(jiǎn)答的 C++ 函數(shù):stringFromJNI(),該函數(shù)返回一個(gè)字符串:”Hello from C++”

  • External Build Files 目錄是存放 CMake 或 ndk-build 構(gòu)建腳本的地方。有點(diǎn)類似于 build.gradle 文件告訴 Gradle 如何編譯你的 APP 一樣,CMake 和 ndk-build 也需要一個(gè)腳本來(lái)告知如何編譯你的 native library。對(duì)于一個(gè)新的項(xiàng)目,Android Studio 創(chuàng)建了一個(gè) CMake 腳本:CMakeLists.txt,并且將其放到了你的 module 的根目錄下

首先還是來(lái)看看代碼吧,比較直觀也比較好理解。

1.查看activity代碼

package cn.hlq.hlqjnipro;

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

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

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

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

首先static靜態(tài)塊去加載so庫(kù),本地編寫(xiě)native方法,調(diào)用方法輸出內(nèi)容。

2.查看native-lib.cpp代碼

#include <jni.h>
#include <string>

extern "C"
JNIEXPORT jstring JNICALL
Java_cn_hlq_hlqjnipro_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

簡(jiǎn)單可以看到,首先定義hello變量,之后return。

3.查看CMakeLists.txt

簡(jiǎn)單的翻譯了下,如有不正之處歡迎指出`

# 使用Android Studio使用CMake的更多信息,閱讀文檔:https://d.android.com/studio/projects/add-native-code.html

# 設(shè)置CMake的最低版本構(gòu)建本機(jī)所需庫(kù)
cmake_minimum_required(VERSION 3.4.1)

# 創(chuàng)建和名稱庫(kù),使它是靜態(tài)的或共享,并提供了相對(duì)路徑的源代碼
# 可以定義多個(gè)圖書(shū)館,CMake將為你構(gòu)建這些內(nèi)容
# Gradle自動(dòng)與你的APK包共享庫(kù)

add_library( # 設(shè)置庫(kù)名稱
             native-lib

             # 集庫(kù)作為一個(gè)共享庫(kù)
             SHARED

             # 提供了一個(gè)相對(duì)路徑你的源文件
             src/main/cpp/native-lib.cpp )

# 搜索指定預(yù)先構(gòu)建的庫(kù)和存儲(chǔ)路徑變量。因?yàn)镃Make包括系統(tǒng)庫(kù)搜索路徑中默認(rèn)情況下,只需要指定想添加公共NDK庫(kù)的名稱,在CMake驗(yàn)證庫(kù)之前存在完成構(gòu)建

find_library( # 設(shè)置path變量的名稱
              log-lib

              # 在CMake定位前指定的NDK庫(kù)名稱
              log )

# 指定庫(kù)CMake應(yīng)該鏈接到目標(biāo)庫(kù)中,可以鏈接多個(gè)庫(kù),比如定義庫(kù),構(gòu)建腳本,預(yù)先構(gòu)建的第三方庫(kù)或者系統(tǒng)庫(kù)

target_link_libraries( # 指定目標(biāo)庫(kù)
                       native-lib

                       # 目標(biāo)庫(kù)到日志庫(kù)的鏈接 包含在NDK
                       ${log-lib} )

一開(kāi)始還覺(jué)的差不多點(diǎn)呢,結(jié)果看到這里越來(lái)越蒙圈,還是先運(yùn)行一下,看看結(jié)果吧。

按照剛才的簡(jiǎn)單分析,這個(gè)demo輸出的結(jié)果應(yīng)該為:Hello from C++ 。一起來(lái)驗(yàn)證一下唄~

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

嗯,確實(shí),輸出了,有些似懂非懂的,繼續(xù)研究~

經(jīng)過(guò)查詢,發(fā)現(xiàn)一個(gè)之前從未關(guān)注的內(nèi)容,那就是從編譯到運(yùn)行示例 APP 的流程到底是怎樣呢,如下:

  1. Gradle 調(diào)用外部構(gòu)建腳本,也就是 CMakeLists.txt;
  2. CMake 會(huì)根據(jù)構(gòu)建腳本的指令去編譯一個(gè) C++ 源文件,也就是 native-lib.cpp,并將編譯后的產(chǎn)物扔進(jìn)共享對(duì)象庫(kù)中,并將其命名為 libnative-lib.so,然后 Gradle 將其打包到 APK 中;
  3. 在運(yùn)行期間,APP 的 MainActivity 會(huì)調(diào)用 System.loadLibrary() 方法,加載 native library。而這個(gè)庫(kù)的原生函數(shù),stringFromJNI(),就可以為 APP 所用了;
  4. MainActivity.onCreate() 方法會(huì)調(diào)用 stringFromJNI(),然后返回 “Hello from C++”,并更新 TextView 的顯示;

注意:Instant Run 并不兼容使用了 native code 的項(xiàng)目。Android Studio 會(huì)自動(dòng)禁止 Instant Run 功能。

如果你想驗(yàn)證一下 Gradle 是否將 native library 打包進(jìn)了 APK,你可以使用 APK Analyzer:

  • 選擇 Build > Analyze APK。

  • 從 app/build/outputs/apk/ 路徑中選擇 APK,并點(diǎn)擊 OK。

  • 如下圖,在 APK Analyzer 窗口中,選擇 lib/<ABI>/,你就可以看見(jiàn) libnative-lib.so

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

轉(zhuǎn)自:http://blog.csdn.net/wl9739/article/details/52607010

仿造demo來(lái)一下,首先布局中新增一個(gè)TextView,activity中編寫(xiě)一個(gè)native方法,調(diào)用native方法并輸出結(jié)果,如下:

        TextView tv1 = (TextView) findViewById(R.id.sample_text_1);
        tv1.setText(hlqFromJNI());
    public native String hlqFromJNI();

在cpp中這么玩下:

#include <jni.h>
#include <string>

extern "C" {
JNIEXPORT jstring JNICALL
Java_cn_hlq_hlqjnipro_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

JNIEXPORT jstring JNICALL
Java_cn_hlq_hlqjnipro_MainActivity_hlqFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "真惡心啊 Fuck";
    return env->NewStringUTF(hello.c_str());
}

}

大家有沒(méi)有注意到Java_cn_hlq_hlqjnipro_MainActivity_hlqFromJNI這個(gè)名稱,方法名必須為Java_包名全路徑_方法名

運(yùn)行結(jié)果如下:

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

一般情況下,Gradle 會(huì)將你的本地庫(kù)構(gòu)建成 .so 文件,然后將其打包到你的 APK 中。如果你想 Gradle 構(gòu)建并打包某個(gè)特定的 ABI 。你可以在你的 module 層級(jí)的 build.gradle 文件中使用 ndk.abiFilters 標(biāo)簽來(lái)指定他們:

android {
  ...
  defaultConfig {
    ...
    externalNativeBuild {
      cmake {...}
      // or ndkBuild {...}
    }

    ndk {
      // Specifies the ABI configurations of your native
      // libraries Gradle should build and package with your APK.
      abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',
                   'arm64-v8a'
    }
  }
  buildTypes {...}
  externalNativeBuild {...}
}

提供給別人使用

ReBuild Project之后,將生成好的so庫(kù)提供有需要的人即可,不過(guò)要記得調(diào)用的時(shí)候包名要一致,不然會(huì)報(bào)一個(gè)找不到so的問(wèn)題。

LZ簡(jiǎn)單寫(xiě)了一個(gè)測(cè)試demo,如下圖:

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

運(yùn)行結(jié)果如下:

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

比較惡心的就是包名這塊,等以后再看看有沒(méi)有好的解決辦法吧。

拓展APP構(gòu)建流程

查看官方文檔中,突然發(fā)現(xiàn)有關(guān)構(gòu)建流程內(nèi)容,一起了解下,如下:

構(gòu)建流程涉及許多將您的項(xiàng)目轉(zhuǎn)換成 Android 應(yīng)用軟件包 (APK)的工具和流程。構(gòu)建流程非常靈活,因此了解它的一些底層工作原理會(huì)很有幫助。

典型 Android 應(yīng)用模塊的構(gòu)建流程圖如下:

<center>
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

典型 Android 應(yīng)用模塊的構(gòu)建流程通常依循下列步驟:

1.編譯器將您的源代碼轉(zhuǎn)換成 DEX(Dalvik Executable) 文件(其中包括運(yùn)行在 Android 設(shè)備上的字節(jié)碼),將所有其他內(nèi)容轉(zhuǎn)換成已編譯資源;

2.APK 打包器將 DEX 文件和已編譯資源合并成單個(gè) APK。不過(guò),必須先簽署 APK,才能將應(yīng)用安裝并部署到 Android 設(shè)備上;

3.APK 打包器使用調(diào)試或發(fā)布密鑰庫(kù)簽署您的 APK:

a. 如果您構(gòu)建的是調(diào)試版本的應(yīng)用(即專用于測(cè)試和分析的應(yīng)用),打包器會(huì)使用調(diào)試密鑰庫(kù)簽署您的應(yīng)用。Android Studio 自動(dòng)使用調(diào)試密鑰庫(kù)配置新項(xiàng)目;

b. 如果您構(gòu)建的是打算向外發(fā)布的發(fā)布版本應(yīng)用,打包器會(huì)使用發(fā)布密鑰庫(kù)簽署您的應(yīng)用

4.在生成最終 APK 之前,打包器會(huì)使用 zipalign 工具對(duì)應(yīng)用進(jìn)行優(yōu)化,減少其在設(shè)備上運(yùn)行時(shí)的內(nèi)存占用

構(gòu)建流程結(jié)束時(shí),您將獲得可用來(lái)進(jìn)行部署、測(cè)試的調(diào)試 APK,或者可用來(lái)發(fā)布給外部用戶的發(fā)布 APK。

參考文獻(xiàn)

  1. http://baike.baidu.com/link?url=QrA-HKewzfPKP5UejCXH8JhE4yQs5MhwG6EBYI8imO9k8zYIlM0h2DYffNSqdK8dG6LZLfT0dK5ocK2NEsOUJq
  2. http://blog.csdn.net/tongseng/article/details/53005123
  3. http://www.cnblogs.com/bastard/archive/2012/05/19/2508913.html
  4. http://blog.csdn.net/baidu_26352053/article/details/53931045
  5. https://developer.android.google.cn/ndk/guides/concepts.html
  6. https://developer.android.google.cn/studio/build/index.html;
  7. http://blog.csdn.net/wl9739/article/details/52607010

結(jié)束語(yǔ)

這篇文章寫(xiě)的夠揪心,個(gè)人感覺(jué)亂糟糟的,實(shí)際學(xué)習(xí)的時(shí)候也是亂糟糟的,幾乎都是靠著各種搜索,況且還有一些不靠譜的博文誤導(dǎo)或者說(shuō)是版本有些老。

望觀看者海涵`有問(wèn)題及時(shí)溝通。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容