Skip to content

Commit

Permalink
Merge pull request #108 from prashantsaini1/fix/android-leaks
Browse files Browse the repository at this point in the history
fix: android memory leaks
  • Loading branch information
AndreaVitale authored Dec 9, 2020
2 parents 9df9b8d + b660ad3 commit 6e1f50d
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 47 deletions.
2 changes: 1 addition & 1 deletion android/manifest
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# this is your module manifest and used by Titanium
# during compilation, packaging, distribution, etc.
#
version: 5.0.1
version: 5.0.2
apiversion: 4
architectures: arm64-v8a armeabi-v7a x86 x86_64
description: av.imageview
Expand Down
80 changes: 41 additions & 39 deletions android/src/av/imageview/AvImageView.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package av.imageview;

import android.app.Activity;
import android.annotation.SuppressLint;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;
Expand All @@ -10,41 +10,31 @@
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.DrawableImageViewTarget;
import com.bumptech.glide.signature.ObjectKey;

import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollProxy;
import org.appcelerator.titanium.TiApplication;
import org.appcelerator.titanium.TiBlob;
import org.appcelerator.titanium.proxy.TiViewProxy;
import org.appcelerator.titanium.util.TiConvert;
import org.appcelerator.titanium.view.TiDrawableReference;
import org.appcelerator.titanium.view.TiUIView;

import java.lang.ref.WeakReference;

import av.imageview.utils.ProgressIndicator;
import av.imageview.utils.RequestListener;

public class AvImageView extends TiUIView
{
public class AvImageView extends TiUIView {
private static final String LCAT = "AvImageView";

private WeakReference<TiViewProxy> proxy;
private ImageView imageView;
private ProgressIndicator progressBar;
private RelativeLayout layout;
private RequestListener requestListener;

public AvImageView(Activity context, TiViewProxy proxy) {
public AvImageView(TiViewProxy proxy) {
super(proxy);

this.proxy = new WeakReference<>(proxy);
this.layout = new RelativeLayout(context);
this.imageView = new ImageView(context);
this.progressBar = new ProgressIndicator(context);
this.requestListener = new RequestListener(proxy, this.progressBar);
this.layout = new RelativeLayout(proxy.getActivity());
this.imageView = new ImageView(proxy.getActivity());
this.progressBar = new ProgressIndicator(proxy.getActivity());

this.layout.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
Expand Down Expand Up @@ -91,9 +81,22 @@ public void propertyChanged(String key, Object oldValue, Object newValue, KrollP

@Override
public void release() {
Activity act = TiApplication.getAppCurrentActivity();
if (!act.isFinishing() && !act.isDestroyed()) {
Glide.with(act).clear(this.imageView);
if (this.imageView != null) {
// this line might not be required as calling the clear will eventually stop image-resource being loaded
// but unfortunately it'll try to show the current placeholder
//Glide.with(this.imageView.getContext()).clear(this.imageView);

clearImage();
this.imageView = null;
}

if (this.progressBar != null) {
this.progressBar = null;
}

if (this.layout != null) {
this.layout.removeAllViews();
this.layout = null;
}

super.release();
Expand Down Expand Up @@ -123,19 +126,19 @@ public void processProperty(String withName, KrollDict fromProperties) {
}
}

@SuppressLint("CheckResult")
public void setImageAsURL(String uri) {
Drawable defaultImageDrawable = ImageViewHelper.getDrawableFromProxyProperty("defaultImage", this.proxy.get());
Drawable brokenLinkImageDrawable = ImageViewHelper.getDrawableFromProxyProperty("brokenLinkImage", this.proxy.get());
GlideUrl url = new GlideUrl(uri, ImageViewHelper.prepareRequestHeaders(uri, this.proxy.get()));
Drawable defaultImageDrawable = ImageViewHelper.getDrawableFromProxyProperty("defaultImage", proxy);
Drawable brokenLinkImageDrawable = ImageViewHelper.getDrawableFromProxyProperty("brokenLinkImage", proxy);
GlideUrl url = new GlideUrl(uri, ImageViewHelper.prepareRequestHeaders(uri, proxy));

KrollDict currentProperties = this.proxy.get().getProperties();
KrollDict currentProperties = proxy.getProperties();

int timeout = currentProperties.containsKey("timeout")
? currentProperties.getInt("timeout")
: ImageViewConstants.DEFAULT_REQUEST_TIMEOUT;

RequestOptions options;
RequestBuilder builder;
String signature = "";

// Creating request options
Expand All @@ -144,29 +147,29 @@ public void setImageAsURL(String uri) {
options = options.error(brokenLinkImageDrawable);
options = options.timeout(timeout);

if (currentProperties.containsKey("animated") && !currentProperties.getBoolean("animated")) {
if (currentProperties.containsKeyAndNotNull("animated") && !currentProperties.getBoolean("animated")) {
options = options.dontAnimate();
}

if (currentProperties.containsKey("rounded") && currentProperties.getBoolean("rounded")) {
if (currentProperties.containsKeyAndNotNull("rounded") && currentProperties.getBoolean("rounded")) {
options = options.circleCrop();
}

if (currentProperties.containsKey("shouldCacheImagesInMemory") && !currentProperties.getBoolean("shouldCacheImagesInMemory")) {
if (currentProperties.containsKeyAndNotNull("shouldCacheImagesInMemory") && !currentProperties.getBoolean("shouldCacheImagesInMemory")) {
options = options.skipMemoryCache(true);
}

if (currentProperties.containsKey("loadingIndicator") && currentProperties.getBoolean("loadingIndicator")) {
if (currentProperties.containsKeyAndNotNull("loadingIndicator") && currentProperties.getBoolean("loadingIndicator")) {
this.progressBar.setVisibility(View.VISIBLE);
}

if (currentProperties.containsKey("signature") && currentProperties.getString("signature") != "") {
if (currentProperties.containsKeyAndNotNull("signature") && !currentProperties.getString("signature").isEmpty()) {
signature = currentProperties.getString("signature");
}

// Creating request builder
builder = ImageViewHelper.prepareGlideClientFor(TiApplication.getAppCurrentActivity(), url);
builder = builder.listener(this.requestListener);
RequestBuilder builder = ImageViewHelper.prepareGlideClientFor(proxy.getActivity(), url);
builder = builder.listener(new RequestListener(proxy, this.progressBar));
builder = builder.apply(options);
builder = builder.load(url);
if (signature != null && !signature.equals("")) {
Expand All @@ -176,9 +179,8 @@ public void setImageAsURL(String uri) {
}

public void setImageAsLocalUri(String filename) {
Drawable imageDrawable = TiDrawableReference.fromUrl(this.proxy.get(), filename).getDrawable();
KrollDict currentProperties = this.proxy.get().getProperties();
RequestBuilder builder;
Drawable imageDrawable = TiDrawableReference.fromUrl(proxy, filename).getDrawable();
KrollDict currentProperties = proxy.getProperties();

RequestOptions options = new RequestOptions();

Expand All @@ -191,25 +193,25 @@ public void setImageAsLocalUri(String filename) {
}

// Creating request builder
builder = Glide.with(TiApplication.getAppCurrentActivity()).asDrawable();
builder = builder.listener(this.requestListener);
RequestBuilder<Drawable> builder = Glide.with(proxy.getActivity()).asDrawable();
builder = builder.listener(new RequestListener(proxy, this.progressBar));
builder = builder.apply(options);
builder = builder.load(imageDrawable);

builder.into(this.imageView);
}

public void setImageAsBlob(TiBlob blob) {
TiDrawableReference drawableReference = TiDrawableReference.fromBlob(this.proxy.get().getActivity(), blob);
TiDrawableReference drawableReference = TiDrawableReference.fromBlob(proxy.getActivity(), blob);

this.imageView.setImageBitmap(drawableReference.getBitmap());

if (this.proxy.get().hasListeners(ImageViewConstants.EVENT_IMAGE_LOADED)) {
if (proxy.hasListeners(ImageViewConstants.EVENT_IMAGE_LOADED)) {
KrollDict payload = new KrollDict();

payload.put("image", blob);

this.proxy.get().fireEvent(ImageViewConstants.EVENT_IMAGE_LOADED, payload);
proxy.fireEvent(ImageViewConstants.EVENT_IMAGE_LOADED, payload);
}

if (this.progressBar != null && this.progressBar.getVisibility() == View.VISIBLE) {
Expand Down
7 changes: 1 addition & 6 deletions android/src/av/imageview/ImageViewProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,11 @@
public class ImageViewProxy extends TiViewProxy {
private static final String LCAT = "ImageViewProxy";
private static final boolean DBG = TiConfig.LOGD;

private static final int MSG_FIRST_ID = TiViewProxy.MSG_LAST_ID + 1;

private Activity activity;

@Override
public TiUIView createView(Activity activity) {
this.activity = activity;

TiUIView view = new AvImageView(this.activity, this);
TiUIView view = new AvImageView(this);

view.getLayoutParams().autoFillsHeight = false;
view.getLayoutParams().autoFillsWidth = false;
Expand Down
7 changes: 6 additions & 1 deletion android/src/av/imageview/utils/RequestListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ public boolean onLoadFailed(@Nullable GlideException e, Object model, Target tar
KrollDict payload = new KrollDict();

payload.put("image", currentProperties.getString("image"));
payload.put("reason", e.getMessage());

if (e != null) {
payload.put("reason", e.getMessage());
} else {
payload.put("reason", "unknown");
}

this.proxy.get().fireEvent(ImageViewConstants.EVENT_IMAGE_LOAD_ERROR, payload);
}
Expand Down

0 comments on commit 6e1f50d

Please sign in to comment.