Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(android): optimize ImageView image download peformance #13078

Merged
merged 11 commits into from
Sep 23, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import org.appcelerator.kroll.util.KrollAssetHelper;
import org.appcelerator.titanium.util.TiBlobLruCache;
import org.appcelerator.titanium.util.TiFileHelper;
import org.appcelerator.titanium.util.TiImageLruCache;
import org.appcelerator.titanium.util.TiImageCache;
import org.appcelerator.titanium.util.TiResponseCache;
import org.appcelerator.titanium.util.TiUIHelper;
import org.appcelerator.titanium.util.TiWeakList;
Expand Down Expand Up @@ -388,7 +388,7 @@ public void onLowMemory()
{
// Release all the cached images
TiBlobLruCache.getInstance().evictAll();
TiImageLruCache.getInstance().evictAll();
TiImageCache.clear();

// Perform hard garbage collection to reclaim memory.
if (KrollRuntime.getInstance() != null) {
Expand All @@ -405,7 +405,7 @@ public void onTrimMemory(int level)
if (level >= TRIM_MEMORY_RUNNING_LOW) {
// Release all the cached images
TiBlobLruCache.getInstance().evictAll();
TiImageLruCache.getInstance().evictAll();
TiImageCache.clear();

// Perform soft garbage collection to reclaim memory.
if (KrollRuntime.getInstance() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,35 @@ protected TiBaseFile(int type)
this.binary = false;
}

@Override
public boolean equals(Object value)
{
// Not equal if given null.
if (value == null) {
return false;
}

// Check if give object is same type as this instance such as TiFile, TiResourceFile, etc.
if (value.getClass().equals(getClass()) == false) {
return false;
}

// Compare native paths. (This can return null.)
String thisNativePath = nativePath();
String givenNativePath = ((TiBaseFile) value).nativePath();
if (thisNativePath == null) {
return (givenNativePath == null);
}
return thisNativePath.equals(givenNativePath);
}

@Override
public int hashCode()
{
String nativePath = nativePath();
return (nativePath != null) ? nativePath.hashCode() : 0;
}

/**
* @return true if the file is a File, false otherwise. See {@link java.io.File#isFile()} for more details.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,14 @@ public DownloadJob(URI uri)

public void run()
{
boolean wasSuccessful = false;
try {
// Download the file/content referenced by the URI.
// Once all content has been pumped below, content will be made available via "TiResponseCache".
try (InputStream stream = blockingDownload(uri)) {
if (stream != null) {
KrollStreamHelper.pump(stream, null);
wasSuccessful = true;
}
}

Expand Down Expand Up @@ -348,15 +350,17 @@ public void run()
}
}
}

sendMessage(uri, MSG_FIRE_DOWNLOAD_FINISHED);
} catch (Exception e) {

wasSuccessful = false;
Log.e(TAG, "Exception downloading from: " + uri + "\n" + e.getMessage());
} finally {
downloadingURIs.remove(uri.toString());
}

// fire a download fail event if we are unable to download
if (wasSuccessful) {
sendMessage(uri, MSG_FIRE_DOWNLOAD_FINISHED);
} else {
sendMessage(uri, MSG_FIRE_DOWNLOAD_FAILED);
Log.e(TAG, "Exception downloading from: " + uri + "\n" + e.getMessage());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2021 by Axway, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
package org.appcelerator.titanium.util;

import android.graphics.Bitmap;
import org.appcelerator.kroll.KrollRuntime;
import org.appcelerator.titanium.view.TiDrawableReference;
import java.lang.ref.SoftReference;
import java.util.HashMap;

public final class TiImageCache
{
private static final HashMap<TiDrawableReference.Key, SoftReference<Bitmap>> bitmapCollection = new HashMap<>(64);
private static final HashMap<TiDrawableReference.Key, TiExifOrientation> orientationCollection = new HashMap<>(64);

static
{
KrollRuntime.addOnDisposingListener((KrollRuntime runtime) -> {
clear();
});
}

private TiImageCache()
{
}

public static synchronized void add(TiImageInfo imageInfo)
{
if ((imageInfo != null) && (imageInfo.getKey() != null) && (imageInfo.getBitmap() != null)) {
Bitmap bitmap = imageInfo.getBitmap();
if ((bitmap != null) && !bitmap.isRecycled()) {
bitmapCollection.put(imageInfo.getKey(), new SoftReference<>(imageInfo.getBitmap()));
orientationCollection.put(imageInfo.getKey(), imageInfo.getOrientation());
}
}
}

public static synchronized Bitmap getBitmap(TiDrawableReference.Key key)
{
var bitmapRef = bitmapCollection.get(key);
if (bitmapRef != null) {
var bitmap = bitmapRef.get();
if ((bitmap != null) && !bitmap.isRecycled()) {
return bitmap;
} else {
remove(key);
}
}
return null;
}

public static synchronized TiExifOrientation getOrientation(TiDrawableReference.Key key)
{
return orientationCollection.get(key);
}

public static synchronized void clear()
{
bitmapCollection.clear();
orientationCollection.clear();
}

private static synchronized void remove(TiDrawableReference.Key key)
{
bitmapCollection.remove(key);
orientationCollection.remove(key);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2021 by Axway, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
package org.appcelerator.titanium.util;

import android.graphics.Bitmap;
import org.appcelerator.titanium.view.TiDrawableReference;

public class TiImageInfo
{
private final TiDrawableReference.Key key;
private final Bitmap bitmap;
private final TiExifOrientation orientation;

public TiImageInfo(TiDrawableReference.Key key, Bitmap bitmap, TiExifOrientation orientation)
{
this.key = key;
this.bitmap = bitmap;
this.orientation = orientation;
}

@Override
public boolean equals(Object value)
{
if (value instanceof TiImageInfo) {
return ((TiImageInfo) value).key.equals(this.key);
}
return false;
}

@Override
public int hashCode()
{
return (this.key != null) ? this.key.hashCode() : 0;
}

public TiDrawableReference.Key getKey()
{
return this.key;
}

public Bitmap getBitmap()
{
return this.bitmap;
}

public TiExifOrientation getOrientation()
{
return this.orientation;
}
}

This file was deleted.

This file was deleted.

Loading