mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-07 16:54:52 +00:00
refactor Image load with Fresco image
refactor Image load with Fresco image(Android)
This commit is contained in:
@@ -9,29 +9,28 @@
|
|||||||
|
|
||||||
package com.horcrux.svg;
|
package com.horcrux.svg;
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.provider.MediaStore;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.facebook.common.executors.CallerThreadExecutor;
|
||||||
|
import com.facebook.common.references.CloseableReference;
|
||||||
|
import com.facebook.datasource.DataSource;
|
||||||
import com.facebook.common.logging.FLog;
|
import com.facebook.common.logging.FLog;
|
||||||
import com.facebook.common.util.UriUtil;
|
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||||
|
import com.facebook.imagepipeline.core.ImagePipeline;
|
||||||
|
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
|
||||||
|
import com.facebook.imagepipeline.image.CloseableImage;
|
||||||
|
import com.facebook.imagepipeline.request.ImageRequest;
|
||||||
|
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
||||||
import com.facebook.react.bridge.ReadableMap;
|
import com.facebook.react.bridge.ReadableMap;
|
||||||
import com.facebook.react.common.ReactConstants;
|
import com.facebook.react.common.ReactConstants;
|
||||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,54 +44,8 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode {
|
|||||||
private String mH;
|
private String mH;
|
||||||
private Uri mUri;
|
private Uri mUri;
|
||||||
private Bitmap mBitmap;
|
private Bitmap mBitmap;
|
||||||
private boolean mLocalImage;
|
|
||||||
private boolean mLoading;
|
private boolean mLoading;
|
||||||
|
|
||||||
private class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
|
|
||||||
private final Canvas mCanvas;
|
|
||||||
private final Paint mPaint;
|
|
||||||
private RNSVGSvgViewShadowNode mSvgShadowNode;
|
|
||||||
public BitmapWorkerTask(Canvas canvas, Paint paint, RNSVGSvgViewShadowNode node) {
|
|
||||||
// Use a WeakReference to ensure the ImageView can be garbage collected
|
|
||||||
mCanvas = canvas;
|
|
||||||
mPaint = paint;
|
|
||||||
mSvgShadowNode = node;
|
|
||||||
mSvgShadowNode.increaseCounter();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode image in background.
|
|
||||||
@Override
|
|
||||||
protected Bitmap doInBackground(Integer... params) {
|
|
||||||
Bitmap bitmap= null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (mLocalImage) {
|
|
||||||
ContentResolver resolver = getThemedContext().getContentResolver();
|
|
||||||
bitmap = MediaStore.Images.Media.getBitmap(resolver, mUri);
|
|
||||||
} else {
|
|
||||||
URL url = new URL(mUri.toString());
|
|
||||||
bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
FLog.w(ReactConstants.TAG, "RNSVG: load Image load failed!:" + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Once complete, see if ImageView is still around and set bitmap.
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(@Nullable Bitmap bitmap) {
|
|
||||||
if (bitmap != null) {
|
|
||||||
mBitmap = bitmap;
|
|
||||||
mSvgShadowNode.decreaseCounter();
|
|
||||||
mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
|
||||||
mPaint.reset();
|
|
||||||
mSvgShadowNode.drawChildren(mCanvas, mPaint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ReactProp(name = "x")
|
@ReactProp(name = "x")
|
||||||
public void setX(String x) {
|
public void setX(String x) {
|
||||||
mX = x;
|
mX = x;
|
||||||
@@ -120,26 +73,15 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode {
|
|||||||
@ReactProp(name = "src")
|
@ReactProp(name = "src")
|
||||||
public void setSrc(@Nullable ReadableMap src) {
|
public void setSrc(@Nullable ReadableMap src) {
|
||||||
if (src != null) {
|
if (src != null) {
|
||||||
String uri = src.getString("uri");
|
String uriString = src.getString("uri");
|
||||||
if (uri != null) {
|
|
||||||
try {
|
if (uriString == null || uriString.isEmpty()) {
|
||||||
mUri = Uri.parse(uri);
|
//TODO: give warning about this
|
||||||
// Verify scheme is set, so that relative uri (used by static resources) are not handled.
|
return;
|
||||||
if (mUri.getScheme() == null) {
|
|
||||||
mUri = null;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// ignore malformed uri, then attempt to extract resource ID.
|
|
||||||
}
|
|
||||||
if (mUri == null) {
|
|
||||||
mUri = getResourceDrawableUri(getThemedContext(), uri);
|
|
||||||
mLocalImage = true;
|
|
||||||
} else {
|
|
||||||
mLocalImage = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mUri = Uri.parse(uriString);
|
||||||
}
|
}
|
||||||
markUpdated();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -157,37 +99,36 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode {
|
|||||||
|
|
||||||
restoreCanvas(canvas, count);
|
restoreCanvas(canvas, count);
|
||||||
markUpdateSeen();
|
markUpdateSeen();
|
||||||
|
|
||||||
if (node.isCounterEmpty()) {
|
|
||||||
mBitmap.recycle();
|
|
||||||
}
|
|
||||||
} else if (!mLoading) {
|
} else if (!mLoading) {
|
||||||
mLoading = true;
|
mLoading = true;
|
||||||
loadBitmap(getResourceDrawableId(getThemedContext(), null), canvas, paint, node);
|
loadBitmap(canvas, paint, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadBitmap(int resId, Canvas canvas, Paint paint, RNSVGSvgViewShadowNode node) {
|
public void loadBitmap(final Canvas canvas, final Paint paint, final RNSVGSvgViewShadowNode node) {
|
||||||
BitmapWorkerTask task = new BitmapWorkerTask(canvas, paint, node);
|
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(mUri).build();
|
||||||
task.execute(resId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getResourceDrawableId(Context context, @Nullable String name) {
|
ImagePipeline imagePipeline = Fresco.getImagePipeline();
|
||||||
if (name == null || name.isEmpty()) {
|
DataSource<CloseableReference<CloseableImage>>
|
||||||
return 0;
|
dataSource = imagePipeline.fetchDecodedImage(request, getThemedContext());
|
||||||
}
|
dataSource.subscribe(new BaseBitmapDataSubscriber() {
|
||||||
return context.getResources().getIdentifier(
|
@Override
|
||||||
name.toLowerCase().replace("-", "_"),
|
public void onNewResultImpl(@Nullable Bitmap bitmap) {
|
||||||
"drawable",
|
if (bitmap != null) {
|
||||||
context.getPackageName());
|
mBitmap = bitmap;
|
||||||
}
|
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
||||||
|
paint.reset();
|
||||||
|
node.drawChildren(canvas, paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
private static Uri getResourceDrawableUri(Context context, @Nullable String name) {
|
public void onFailureImpl(DataSource dataSource) {
|
||||||
int resId = getResourceDrawableId(context, name);
|
// No cleanup required here.
|
||||||
return resId > 0 ? new Uri.Builder()
|
// TODO: more details about this failure
|
||||||
.scheme(UriUtil.LOCAL_RESOURCE_SCHEME)
|
FLog.w(ReactConstants.TAG, "RNSVG: load Image load failed!:");
|
||||||
.path(String.valueOf(resId))
|
}
|
||||||
.build() : Uri.EMPTY;
|
},
|
||||||
|
CallerThreadExecutor.getInstance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ package com.horcrux.svg;
|
|||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.facebook.csslayout.CSSNode;
|
|
||||||
import com.facebook.csslayout.MeasureOutput;
|
|
||||||
import com.facebook.react.uimanager.BaseViewManager;
|
|
||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
import com.facebook.react.uimanager.ThemedReactContext;
|
||||||
import com.facebook.react.uimanager.ViewGroupManager;
|
import com.facebook.react.uimanager.ViewGroupManager;
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
|
public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
|
||||||
|
|
||||||
private int mCounter = 0;
|
|
||||||
|
|
||||||
private boolean mTouchable = false;
|
private boolean mTouchable = false;
|
||||||
|
|
||||||
private static final Map<String, Path> mDefinedClipPaths = new HashMap<>();
|
private static final Map<String, Path> mDefinedClipPaths = new HashMap<>();
|
||||||
@@ -101,16 +99,4 @@ public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
|
|||||||
public Path getDefinedClipPath(String clipPathId) {
|
public Path getDefinedClipPath(String clipPathId) {
|
||||||
return mDefinedClipPaths.get(clipPathId);
|
return mDefinedClipPaths.get(clipPathId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void increaseCounter() {
|
|
||||||
mCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void decreaseCounter() {
|
|
||||||
mCounter--;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCounterEmpty() {
|
|
||||||
return mCounter == 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user