V2EX kovli
kovli

kovli

V2EX 第 351330 号会员,加入于 2018-09-21 16:36:38 +08:00
一个追逐全栈的程序员。12年开始从事iOS原生开发,目前的工作内容是iOS、安卓平台的APP设计开发及服务端的开发和运维,专注于跨平台开发、Javascript、Node.js等技术。我喜欢敲代码,也喜欢写博客。
kovli 最近回复了
2019-04-28 14:16:26 +08:00
回复了 kovli 创建的主题 React ReactNative 开发笔记(持续更新...)
- 如何在原生端( iOS 和 android 两个平台)使用 ReactNative 里的本地图片(路径类似 require('./xxximage.png'))。
在 ReactNative 开发过程中,有时需要在原生端显示 RN 里的图片,这样的好处是可以通过热更新来更新 APP 里的图片,而不需要发布原生版本,而 ReactNative 里图片路径是相对路径,类似'./xxximage.png'的写法,原生端是无法解析这类路径,那么如果将 RN 的图片传递给原生端呢?

解决方案:

1、图片如果用网络图,那只需要将 url 字符串地址传递给原生即可,这种做法需要时间和网络环境加载图片,不属于本地图片,不是本方案所追求的最佳方式。

2、懒人做法是把 RN 的本地图片生成 base64 字符串然后传递给原生再解析,这种做法如果图片太大,字符串会相当长,同样不认为是最佳方案。

其实 RN 提供了相关的解决方法,如下:

RN 端

const myImage = require('./my-image.png');
const resolveAssetSource = require('react-native/Libraries/Image/resolveAssetSource');
const resolvedImage = resolveAssetSource(myImage);
NativeModules.NativeBridge.showRNImage(resolvedImage);

iOS 端

#import <React/RCTConvert.h>


RCT_EXPORT_METHOD(showRNImage:(id)rnImageData){
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *rnImage = [RCTConvert UIImage:rnImageData];
...
});
}

安卓端

第一步,从桥接文件获取到 uri 地址


@ReactMethod
public static void showRNImage(Activity activity, ReadableMap params){
String rnImageUri;
try {
//图片地址
rnImageUri = params.getString("uri");
Log.i("Jumping", "uri : " + uri);

...

} catch (Exception e) {
return;
}
}

第二步,创建 JsDevImageLoader.java


package com.XXX;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.StrictMode;
import android.support.annotation.NonNull;
import android.util.Log;


import com.XXX.NavigationApplication;

import java.io.IOException;
import java.net.URL;

public class JsDevImageLoader {
private static final String TAG = "JsDevImageLoader";
public static Drawable loadIcon(String iconDevUri) {
try {
StrictMode.ThreadPolicy threadPolicy = StrictMode.getThreadPolicy();
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build());

Drawable drawable = tryLoadIcon(iconDevUri);

StrictMode.setThreadPolicy(threadPolicy);
return drawable;
} catch (Exception e) {
Log.e(TAG, "Unable to load icon: " + iconDevUri);
return new BitmapDrawable();
}
}

@NonNull
private static Drawable tryLoadIcon(String iconDevUri) throws IOException {
URL url = new URL(iconDevUri);
Bitmap bitmap = BitmapFactory.decodeStream(url.openStream());
return new BitmapDrawable(NavigationApplication.instance.getResources(), bitmap);
}
}
第三步,导入 ResourceDrawableIdHelper.java


package com.xg.navigation.react;// Copyright 2004-present Facebook. All Rights Reserved.

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;

import com.facebook.common.util.UriUtil;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Nullable;

/**
* Direct copy paste from react-native, because they made that class package scope. -_-"
* Can be deleted in react-native ^0.29
*/
public class ResourceDrawableIdHelper {
public static final ResourceDrawableIdHelper instance = new ResourceDrawableIdHelper();

private Map<String, Integer> mResourceDrawableIdMap;

public ResourceDrawableIdHelper() {
mResourceDrawableIdMap = new HashMap<>();
}

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;
}

@Nullable
public Drawable getResourceDrawable(Context context, @Nullable String name) {
int resId = getResourceDrawableId(context, name);
return resId > 0 ? context.getResources().getDrawable(resId) : null;
}

public Uri getResourceDrawableUri(Context context, @Nullable String name) {
int resId = getResourceDrawableId(context, name);
return resId > 0 ? new Uri.Builder()
.scheme(UriUtil.LOCAL_RESOURCE_SCHEME)
.path(String.valueOf(resId))
.build() : Uri.EMPTY;
}
}

第四步,创建 BitmapUtil.java


package com.XXX;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import andrid.graphics.drawable.Drawable;
import android.net.Uri;
import android.provider.MediaStore;
import android.text.TextUtils;

import com.XXX.NavigationApplication;
import com.XXX.JsDevImageLoader;
import com.XXX.ResourceDrawableIdHelper;

import java.io.IOException;


public class BitmapUtil {

private static final String FILE_SCHEME = "file";

public static Drawable loadImage(String iconSource) {

if (TextUtils.isEmpty(iconSource)) {
return null;
}

if (NavigationApplication.instance.isDebug()) {
return JsDevImageLoader.loadIcon(iconSource);
} else {
Uri uri = Uri.parse(iconSource);
if (isLocalFile(uri)) {
return loadFile(uri);
} else {
return loadResource(iconSource);
}
}
}

private static boolean isLocalFile(Uri uri) {
return FILE_SCHEME.equals(uri.getScheme());
}

private static Drawable loadFile(Uri uri) {
Bitmap bitmap = BitmapFactory.decodeFile(uri.getPath());
return new BitmapDrawable(NavigationApplication.instance.getResources(), bitmap);
}

private static Drawable loadResource(String iconSource) {
return ResourceDrawableIdHelper.instance.getResourceDrawable(NavigationApplication.instance, iconSource);
}

public static Bitmap getBitmap(Activity activity, String uri) {

if (activity == null || uri == null || TextUtils.isEmpty(uri)) {
return null;
}

Uri mImageCaptureUri;
try {
mImageCaptureUri = Uri.parse(uri);
} catch (Exception e) {
e.printStackTrace();
return null;
}

if (mImageCaptureUri == null) {
return null;
}

Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(activity.getContentResolver(), mImageCaptureUri);
} catch (IOException e) {
e.printStackTrace();
return null;
}

return bitmap;
}
}

第五步,使用第一步里的 rnImageUri 地址

...
BitmapUtil.loadImage(rnImageUri)
...

第六步,显示图片


import android.widget.RelativeLayout;
import android.support.v7.widget.AppCompatImageView;
import android.graphics.drawable.Drawable;

...
final RelativeLayout item = (RelativeLayout) mBottomBar.getChildAt(i);
final AppCompatImageView itemIcon = (AppCompatImageView) item.getChildAt(0);
itemIcon.setImageDrawable(BitmapUtil.loadImage(rnImageUri));

...
2019-01-26 10:50:10 +08:00
回复了 kovli 创建的主题 React ReactNative 开发笔记(持续更新...)
不可以编辑主题,好吧,以后通过回复来更新我的博文。

- 升级旧 RN 版本到目前最新的 0.57.8 如果采用手动升级需要注意如下。
I upgraded from react-naitve 0.55.4 to react-native 0.57.0 and I get this error bundling failed: Error: The 'decorators' plugin requires a 'decoratorsBeforeExport' option, whose value must be a boolean. If you are migrating from Babylon/Babel 6 or want to use the old decorators proposal, you should use the 'decorators-legacy' plugin instead of 'decorators'.

解决方案:参考如下例子

First install the new proposal decorators with npm install @babel/plugin-proposal-decorators --save-dev or yarn add @babel/plugin-proposal-decorators --dev

Then, inside of your .babelrc file, change this:

{
"presets": ["react-native"],
"plugins": ["transform-decorators-legacy"]
}
To this:

{
"presets": [
"module:metro-react-native-babel-preset",
"@babel/preset-flow"
],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy" : true }]
]
}

EDIT:

After you've updated your .babelrc file, make sure to add preset-flow as well with the command yarn add @babel/preset-flow --dev or npm install @babel/preset-flow --save-dev
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4963 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 16ms UTC 09:24 PVG 17:24 LAX 01:24 JFK 04:24
Do have faith in what you're doing.
ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86