主要參考
整合簡述
整合的程式碼是在AndroidTensorFlowMachineLearningExample基礎上修改.
Android上整合tensorflow最簡單是步驟是:
1 complile引入
compile 'org.tensorflow:tensorflow-android:1.4.0'
複製程式碼
2 拿到AI演算法開發人員訓練好並壓縮好的pb檔案
3 根據其java的api開始寫程式碼
一般so庫通過compile引入後自動會打入,pb放在asserts資料夾,但這樣會增大apk包體積. so庫一般一個abi就10-15M,pb檔案20-100M不等. 所以需要動態載入: 放在伺服器,下載到本地,需要時直接從本地讀取.
pb檔案的載入
AndroidTensorFlowMachineLearningExample中api並無從流中載入pb檔案的api,而1.4.0中java api提供了以下構造方法,可以從檔案中載入. 只要預先下載好就行了.
new TensorFlowInferenceInterface(inputStream);
複製程式碼
so庫的動態載入
略顯麻煩, 一需要識別所支援的abi,然後下載對應的so檔案 二 需要註釋掉java程式碼中的靜態程式碼塊載入so庫的程式碼
依賴引入方式不再是上方的一行程式碼compile,而是將gradle快取中的tensorflow-android:1.4.0的jar包和jni包拷貝出來. jni包中的so檔案上傳到伺服器.
註釋靜態方法中的載入so庫的程式碼:
jar包需要註釋掉裡面靜態程式碼塊載入so庫的程式碼: jar包中多處呼叫TensorFlow.init()初始化,所以只要註釋init內部內容就好.
TensorFlow類中的:
static void init() {
//NativeLibrary.load();//註釋掉此行,由我們自己動態載入
}
static {
init();
}
複製程式碼
操作方法:
新建一個包名相同的TensorFlow類,將jar包中程式碼拷貝至此,註釋掉那一行程式碼,用java7(不能用java8)編譯後, 將jar包用winrar開啟,將編譯後的class檔案拖進jar包替換即可. 然後將jar包新增到工程libs目錄,新增為依賴.
so庫動態載入
獲取手機系統首選abi,然後去獲取對應url,下載到app內目錄,載入即可.
獲取首選abi:
private static String getFirstSupportedAbi() {
String abi1 = "";
if (Build.VERSION.SDK_INT >= 21) {
String[] abis = Build.SUPPORTED_ABIS;
if (abis != null) {
String abistr = "";
//第一個是原生支援的,後面的是相容模式.雖然是相容,但手動載入時很多並不相容.
abi1 = abis[0];
for (String abi : abis) {
abistr = abistr + abi+",";
}
if(showLog)
Log.e(TAG, "[copySo] supported api:" + abistr);
}
} else {
if(showLog)
Log.e(TAG, "[copySo] supported api:" + Build.CPU_ABI + "--- " + Build.CPU_ABI2);
if (!TextUtils.isEmpty(Build.CPU_ABI)) {
abi1 = Build.CPU_ABI;
} else if (!TextUtils.isEmpty(Build.CPU_ABI2)) {
abi1 = Build.CPU_ABI2;
}
}
return abi1;
}
複製程式碼
下載後的so檔案要放到app內目錄,不要放到sd卡:
String abi = getFirstSupportedAbi();
File dir = context.getDir("jnilibs", Context.MODE_PRIVATE);
File subDir = new File(dir, abi);
複製程式碼
載入so:
try {
System.load(filePath);
}catch (Throwable e){
e.printStackTrace();
}
複製程式碼
檔案下載
都是大檔案,選一個比較靠譜,能夠斷點續傳的庫:FileDownloader
同時還需要注意:
- 檔案很大,只在wifi時下載,以免耗流量
- 下載完校驗md5.