Skip to content

Commit

Permalink
Merge pull request #3811 from pingwang2011/timob-11282-3_0_X
Browse files Browse the repository at this point in the history
Timob 11282 3 0 x: Android TableView with remote images is very slow
  • Loading branch information
ayeung committed Jan 29, 2013
2 parents d6dfa42 + d5a36c4 commit 7fce4ef
Showing 1 changed file with 190 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

Expand Down Expand Up @@ -42,6 +43,7 @@
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
Expand Down Expand Up @@ -81,9 +83,65 @@ public class TiUIImageView extends TiUIView implements OnLifecycleEvent, Handler

private ArrayList<TiDrawableReference> imageSources;
private TiDrawableReference defaultImageSource;
private TiDownloadListener downloadListener;
private int decodeRetries = 0;
private Object releasedLock = new Object();
private String currentUrl;

final class ImageDownloadListener implements TiDownloadListener {
public int mToken;
public ImageArgs mImageArgs;

public ImageDownloadListener(int token, ImageArgs imageArgs) {
mToken = token;
mImageArgs = imageArgs;
}

public ImageDownloadListener() {}

public int getToken() {
return mToken;
}
@Override
public void downloadFinished(URI uri)
{
if (!TiResponseCache.peek(uri)) {
// The requested image did not make it into our TiResponseCache,
// possibly because it had a header forbidding that. Now get it
// via the "old way" (not relying on cache).
synchronized (imageTokenGenerator) {
token = imageTokenGenerator.incrementAndGet();
if (uri.toString().equals(currentUrl))
{
makeImageSource(uri.toString()).getBitmapAsync(new BgImageLoader(requestedWidth,
requestedHeight, token));
}
}
} else {
firedLoad = false;
if (uri.toString().equals(currentUrl)) {
ImageArgs imageArgs = new ImageArgs(makeImageSource(uri.toString()), getParentView(), requestedWidth,
requestedHeight,
true,
false);
BackgroundImageTask task = new BackgroundImageTask();
try {
task.execute(imageArgs);
} catch (RejectedExecutionException e) {
Log.e(TAG, "Cannot load the image. Loading too many images at the same time.");
}
}
}
}

@Override
public void downloadFailed()
{
// If the download failed, fire an error event
fireError();
}
};

ImageDownloadListener imageDownloadListener = new ImageDownloadListener();

private class BgImageLoader extends TiBackgroundImageLoadTask
{
Expand Down Expand Up @@ -159,35 +217,7 @@ public void sizeChanged(int w, int h, int oldWidth, int oldHeight)
setImage(true);
}
});

downloadListener = new TiDownloadListener()
{
@Override
public void downloadFinished(URI uri)
{
if (!TiResponseCache.peek(uri)) {
// The requested image did not make it into our TiResponseCache,
// possibly because it had a header forbidding that. Now get it
// via the "old way" (not relying on cache).
synchronized (imageTokenGenerator) {
token = imageTokenGenerator.incrementAndGet();
if (imageSources != null && imageSources.size() > 0) {
imageSources.get(0).getBitmapAsync(new BgImageLoader(requestedWidth, requestedHeight, token));
}
}
} else {
firedLoad = false;
setImage(true);
}
}

@Override
public void downloadFailed()
{
// If the download failed, fire an error event
fireError();
}
};

setNativeView(view);
// TODO proxy.getActivity().addOnLifecycleEventListener(this);
}
Expand Down Expand Up @@ -241,6 +271,7 @@ private void setImageDrawable(Drawable d, int token)
}
}


private Handler handler = new Handler(Looper.getMainLooper(), this);
private static final int SET_IMAGE = 10001;
private static final int START = 10002;
Expand Down Expand Up @@ -287,6 +318,8 @@ private void handleSetImage(final Bitmap bitmap)
// what the current bitmap should be.
imageViewProxy.onBitmapChanged(this, bitmap);
}



private class BitmapWithIndex
{
Expand Down Expand Up @@ -696,9 +729,113 @@ private void setDefaultImageSource(Object object)
defaultImageSource = TiDrawableReference.fromObject(proxy.getActivity(), object);
}
}

final class ImageArgs {
public View mView;
public boolean mRecycle;
public TiDrawableReference mImageref;
public TiDimension mRequestedWidth;
public TiDimension mRequestedHeight;
public boolean mNetworkURL;


public ImageArgs(TiDrawableReference imageref, View view,
TiDimension requestedWidth, TiDimension requestedHeight, boolean recycle,
boolean networkURL) {
mView = view;
mImageref = imageref;
mRequestedWidth = requestedWidth;
mRequestedHeight = requestedHeight;
mRecycle = recycle;
mNetworkURL = networkURL;


}
}

private void setImage(boolean recycle)
final class BackgroundImageTask extends AsyncTask<ImageArgs, Void, Bitmap>
{
private boolean recycle;
private boolean mNetworkURL;
private boolean mAsync = false;
private String mUrl;

@Override
protected Bitmap doInBackground(final ImageArgs... params)
{
final ImageArgs imageArgs = params[0];

recycle = imageArgs.mRecycle;
mNetworkURL = imageArgs.mNetworkURL;
Bitmap bitmap = null;

mUrl = imageArgs.mImageref.getUrl();

if (mNetworkURL) {
boolean getAsync = true;
try {
String imageUrl = TiUrl.getCleanUri(imageArgs.mImageref.getUrl()).toString();

URI uri = new URI(imageUrl);
getAsync = !TiResponseCache.peek(uri); // expensive, don't want to do in UI thread
} catch (URISyntaxException e) {
Log.e(TAG, "URISyntaxException for url " + imageArgs.mImageref.getUrl(), e);
getAsync = false;
} catch (NullPointerException e) {
Log.e(TAG, "NullPointerException for url " + imageArgs.mImageref.getUrl(), e);
getAsync = false;
} catch (Exception e) {
Log.e(TAG, "Caught exception for url" + imageArgs.mImageref.getUrl(), e);
}
if (getAsync) {
//
// We've got to start the download back on the UI thread, if we do it on one
// of the AsyncTask threads it will throw an exception.
//
mAsync = true;

TiMessenger.getMainMessenger().post(new Runnable()
{
@Override
public void run()
{
imageArgs.mImageref.getBitmapAsync(imageDownloadListener);

}
});

} else {
bitmap = (imageArgs.mImageref).getBitmap(imageArgs.mView, imageArgs.mRequestedWidth,
imageArgs.mRequestedHeight);
}
} else {
bitmap = (imageArgs.mImageref).getBitmap(imageArgs.mView, imageArgs.mRequestedWidth,
imageArgs.mRequestedHeight);
}
return bitmap;
}

@Override
protected void onPostExecute(Bitmap result)
{
if (!mNetworkURL || currentUrl.equals(mUrl)) {
if (result != null) {
setImage(result);
if (!firedLoad) {
fireLoad(TiC.PROPERTY_IMAGE);
firedLoad = true;
}
} else {
if (!mAsync) {
retryDecode(recycle);
}
}
}
}
}

private void setImage(boolean recycle) {

if (imageSources == null || imageSources.size() == 0 || imageSources.get(0) == null || imageSources.get(0).isTypeNull()) {
if (defaultImageSource != null) {
setDefaultImage();
Expand All @@ -707,6 +844,7 @@ private void setImage(boolean recycle)
}
return;
}

if (imageSources.size() == 1) {
if (imageViewProxy.inTableView()) {
Bitmap currentBitmap = imageViewProxy.getBitmap();
Expand All @@ -725,43 +863,31 @@ private void setImage(boolean recycle)
if (defaultImageSource != null) {
setDefaultImage();
} else {
TiImageView view = getView();
if (view != null) {
view.setImageDrawable(null, recycle);
}
setImage(null);
}
boolean getAsync = true;
try {
String imageUrl = TiUrl.getCleanUri(imageref.getUrl()).toString();
currentUrl = imageref.getUrl();

ImageArgs imageArgs = new ImageArgs(imageref, getParentView(), requestedWidth, requestedHeight, recycle,
true);

URI uri = new URI(imageUrl);
getAsync = !TiResponseCache.peek(uri);
} catch (URISyntaxException e) {
Log.e(TAG, "URISyntaxException for url " + imageref.getUrl(), e);
getAsync = false;
} catch (NullPointerException e) {
Log.e(TAG, "NullPointerException for url " + imageref.getUrl(), e);
getAsync = false;
}
if (getAsync) {
imageref.getBitmapAsync(downloadListener);
} else {
Bitmap bitmap = imageref.getBitmap(getParentView(), requestedWidth, requestedHeight);
if (bitmap != null) {
setImage(bitmap);
if (!firedLoad) {
fireLoad(TiC.PROPERTY_IMAGE);
firedLoad = true;
}
} else {
retryDecode(recycle);
}
BackgroundImageTask task = new BackgroundImageTask();
try {
task.execute(imageArgs);
} catch (RejectedExecutionException e) {
Log.e(TAG, "Cannot load the image. Loading too many images at the same time.");
}

} else {
setImage(imageref.getBitmap(getParentView(), requestedWidth, requestedHeight));
if (!firedLoad) {
fireLoad(TiC.PROPERTY_IMAGE);
firedLoad = true;
currentUrl = imageref.getUrl();

ImageArgs imageArgs = new ImageArgs(imageref, getParentView(), requestedWidth, requestedHeight, recycle,
false);

BackgroundImageTask task = new BackgroundImageTask();
try {
task.execute(imageArgs);
} catch (RejectedExecutionException e) {
Log.e(TAG, "Cannot load the image. Loading too many images at the same time.");
}
}
} else {
Expand Down

0 comments on commit 7fce4ef

Please sign in to comment.