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文件夾,通過圖片名稱找到對應(yīng)的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文件夾是沒有訪問權(quán)限的啊....那么我們代碼更新了奉芦,圖片要更新改怎么辦,怎么辦嘛剧蹂。
后來微軟的一位做CodePush的作者看不下去了声功,CodePush是什么請谷歌一下。于是咔咔把RN的加載代碼重構(gòu)了宠叼。FB看了說"我去,完美解決嘛!"于是尷尬的合并的代碼先巴。
那么問題來了,是怎么解決的了冒冬!
首先通過require獲取資源的時候回判斷是否為開發(fā)狀態(tài)“DEV”,開發(fā)狀態(tài)就通Node服務(wù)中獲取資源地址伸蚯,非開發(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玩耍吧....