React-Native-For-Android圖片熱更新

RN對圖片加載支持了很多套方案,

//加載遠程圖片
<Image source={{url:'http://www.wacai.com/icon.png'}} />
//加載res類的圖片
<Image source={{url:'icon'}} />
//加載指定文件系統(tǒng)的圖片
<Image source={{url:'file:///sdcard/icon.png'}} />
//這個比較流弊,請看下文介紹
<Image source={require('./assets/img/icon.ong')} 

為啥講require的方式比較流弊了,廢話不流弊FB會推薦這種方案嘛!我們的圖片熱更新全靠他了好嗎!網(wǎng)上的那些什么圖片熱更新的教程都別看。FB在21的版本上已經(jīng)完美解決了。 完美....

熱部署

RN在19之前都是將圖片打包到res文件夾,通過圖片名稱找到對應的ID,然后找到圖片的。下面是Android的實現(xiàn)。

public int getResourceDrawableId(Context context, @Nullable String name) {
    if (name == null || name.isEmpty()) {
      return 0;
    }
    name = name.toLowerCase().replace("-", "_");
    if (mResourceDrawableIdMap.containsKey(name)) {
      return mResourceDrawableIdMap.get(name);
    }
    int id = context.getResources().getIdentifier(
        name,
        "drawable",
        context.getPackageName());
    mResourceDrawableIdMap.put(name, id);
    return id;
  }

但是要知道res文件夾是沒有訪問權限的啊....那么我們代碼更新了,圖片要更新改怎么辦,怎么辦嘛。

后來微軟的一位做CodePush的作者看不下去了,CodePush是什么請谷歌一下。于是咔咔把RN的加載代碼重構了。FB看了說"我去,完美解決嘛!"于是尷尬的合并的代碼。

那么問題來了,是怎么解決的了!

首先通過require獲取資源的時候回判斷是否為開發(fā)狀態(tài)“DEV”,開發(fā)狀態(tài)就通Node服務中獲取資源地址,非開發(fā)狀態(tài)就去組裝native的資源地址

devServerURL ? getPathOnDevserver(devServerURL, asset) : getPathInArchive(asset),

根據(jù)不同的平臺獲取拼接不同的目錄,其中 offlinePath 是從native配置的資源目錄決定的。

function getOfflinePath() {
  if (_offlinePath === undefined) {
    var scriptURL = SourceCode.scriptURL;
    var match = scriptURL && scriptURL.match(/^file:\/\/(\/.*\/)/);
    if (match) {
      _offlinePath = match[1];
    } else {
      _offlinePath = '';
    }
  }

  return _offlinePath;
}

function getPathInArchive(asset) {
  var offlinePath = getOfflinePath();
  if (Platform.OS === 'android') {
    if (offlinePath) {
      // E.g. 'file:///sdcard/AwesomeModule/drawable-mdpi/icon.png'
      return 'file://' + offlinePath + getAssetPathInDrawableFolder(asset);
    }
    // E.g. 'assets_awesomemodule_icon'
    // The Android resource system picks the correct scale.
    return assetPathUtils.getAndroidResourceIdentifier(asset);
  } else {
    // E.g. '/assets/AwesomeModule/icon@2x.png'
    return offlinePath + getScaledAssetPath(asset);
  }
}

OK 那么我們該如何做圖片的熱部署。

首先我沒有要定義一個js腳步目錄,可以是data目錄也可以是SdCard。注意一定要以/開頭,就算編譯器告訴你這樣可能不對也得以/開頭。

protected String getJSBundleFile() {
  return "/sdcard/bundle/index.android.bundle";
}

然后打包,把打出的bundle和圖片放到這個目錄下。打開你APP玩耍吧....

作者 大光 更多文章 | Github

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

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