diff --git a/android/src/main/java/com/horcrux/svg/RNSVGImageShadowNode.java b/android/src/main/java/com/horcrux/svg/RNSVGImageShadowNode.java index 195afa94..331712f1 100644 --- a/android/src/main/java/com/horcrux/svg/RNSVGImageShadowNode.java +++ b/android/src/main/java/com/horcrux/svg/RNSVGImageShadowNode.java @@ -9,29 +9,28 @@ package com.horcrux.svg; -import android.content.ContentResolver; -import android.content.Context; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; -import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.Rect; -import android.graphics.RectF; import android.net.Uri; -import android.os.AsyncTask; -import android.provider.MediaStore; 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.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.common.ReactConstants; import com.facebook.react.uimanager.annotations.ReactProp; -import java.net.URL; - import javax.annotation.Nullable; /** @@ -45,54 +44,8 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode { private String mH; private Uri mUri; private Bitmap mBitmap; - private boolean mLocalImage; private boolean mLoading; - private class BitmapWorkerTask extends AsyncTask { - 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") public void setX(String x) { mX = x; @@ -120,26 +73,15 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode { @ReactProp(name = "src") public void setSrc(@Nullable ReadableMap src) { if (src != null) { - String uri = src.getString("uri"); - if (uri != null) { - try { - mUri = Uri.parse(uri); - // Verify scheme is set, so that relative uri (used by static resources) are not handled. - 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; - } + String uriString = src.getString("uri"); + + if (uriString == null || uriString.isEmpty()) { + //TODO: give warning about this + return; } + + mUri = Uri.parse(uriString); } - markUpdated(); } @Override @@ -157,37 +99,36 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode { restoreCanvas(canvas, count); markUpdateSeen(); - - if (node.isCounterEmpty()) { - mBitmap.recycle(); - } } else if (!mLoading) { mLoading = true; - loadBitmap(getResourceDrawableId(getThemedContext(), null), canvas, paint, node); + loadBitmap(canvas, paint, node); } } - public void loadBitmap(int resId, Canvas canvas, Paint paint, RNSVGSvgViewShadowNode node) { - BitmapWorkerTask task = new BitmapWorkerTask(canvas, paint, node); - task.execute(resId); - } + public void loadBitmap(final Canvas canvas, final Paint paint, final RNSVGSvgViewShadowNode node) { + ImageRequest request = ImageRequestBuilder.newBuilderWithSource(mUri).build(); - private static int getResourceDrawableId(Context context, @Nullable String name) { - if (name == null || name.isEmpty()) { - return 0; - } - return context.getResources().getIdentifier( - name.toLowerCase().replace("-", "_"), - "drawable", - context.getPackageName()); - } + ImagePipeline imagePipeline = Fresco.getImagePipeline(); + DataSource> + dataSource = imagePipeline.fetchDecodedImage(request, getThemedContext()); + dataSource.subscribe(new BaseBitmapDataSubscriber() { + @Override + public void onNewResultImpl(@Nullable Bitmap bitmap) { + if (bitmap != null) { + mBitmap = bitmap; + canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); + paint.reset(); + node.drawChildren(canvas, paint); + } + } - - private static 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; + @Override + public void onFailureImpl(DataSource dataSource) { + // No cleanup required here. + // TODO: more details about this failure + FLog.w(ReactConstants.TAG, "RNSVG: load Image load failed!:"); + } + }, + CallerThreadExecutor.getInstance()); } } diff --git a/android/src/main/java/com/horcrux/svg/RNSVGSvgViewManager.java b/android/src/main/java/com/horcrux/svg/RNSVGSvgViewManager.java index 5c5e388a..19ec1be3 100644 --- a/android/src/main/java/com/horcrux/svg/RNSVGSvgViewManager.java +++ b/android/src/main/java/com/horcrux/svg/RNSVGSvgViewManager.java @@ -12,9 +12,6 @@ package com.horcrux.svg; import android.graphics.Bitmap; 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.ViewGroupManager; diff --git a/android/src/main/java/com/horcrux/svg/RNSVGSvgViewShadowNode.java b/android/src/main/java/com/horcrux/svg/RNSVGSvgViewShadowNode.java index 37cf1fc4..29874108 100644 --- a/android/src/main/java/com/horcrux/svg/RNSVGSvgViewShadowNode.java +++ b/android/src/main/java/com/horcrux/svg/RNSVGSvgViewShadowNode.java @@ -29,8 +29,6 @@ import java.util.Map; */ public class RNSVGSvgViewShadowNode extends LayoutShadowNode { - private int mCounter = 0; - private boolean mTouchable = false; private static final Map mDefinedClipPaths = new HashMap<>(); @@ -101,16 +99,4 @@ public class RNSVGSvgViewShadowNode extends LayoutShadowNode { public Path getDefinedClipPath(String clipPathId) { return mDefinedClipPaths.get(clipPathId); } - - public void increaseCounter() { - mCounter++; - } - - public void decreaseCounter() { - mCounter--; - } - - public boolean isCounterEmpty() { - return mCounter == 0; - } }