diff --git a/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java b/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java
index 1d950931124..7f9febc43ac 100644
--- a/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java
+++ b/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java
@@ -6,6 +6,9 @@
*/
package org.appcelerator.titanium.util;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.lang.reflect.Constructor;
@@ -18,18 +21,13 @@
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-
+import java.util.concurrent.atomic.AtomicReference;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSocketFactory;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.kroll.util.KrollStreamHelper;
-import org.appcelerator.titanium.io.TiInputStreamWrapper;
import org.appcelerator.titanium.TiApplication;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSocketFactory;
+import org.appcelerator.titanium.io.TiInputStreamWrapper;
/**
* Manages the asynchronous opening of InputStreams from URIs so that
@@ -86,9 +84,9 @@ public void download(URI uri, TiDownloadListener listener)
* @return
* Returns a stream to the file/content being downloaded.
*
- * Returns null if failed to download content or if given an invalid argument.
+ * Throws exception if failed to download content.
*/
- public InputStream blockingDownload(final URI uri)
+ public InputStream blockingDownload(final URI uri) throws Exception
{
// Validate.
if (uri == null) {
@@ -113,46 +111,36 @@ public InputStream blockingDownload(final URI uri)
// Note: Using "HttpUrlConnection" on UI thread will cause a "NetworkOnMainThreadException" to be thrown.
if (TiApplication.isUIThread()) {
// Perform the blocking download on another thread.
- // Downloaded content will be made available via Titanium's "TiResponseCache".
- try {
- Thread thread = new Thread(new Runnable() {
- @Override
- public void run()
- {
- try (InputStream stream = blockingDownload(uri)) {
- if (stream != null) {
- KrollStreamHelper.pump(stream, null);
- }
- } catch (Exception ex) {
- Log.e(TAG, "Exception downloading from: " + uri.toString(), ex);
- }
+ // Downloaded content will be made available via Titanium's "TiResponseCache"
+ AtomicReference exception = new AtomicReference<>(null);
+ Thread thread = new Thread(() -> {
+ try (InputStream stream = blockingDownload(uri)) {
+ if (stream != null) {
+ KrollStreamHelper.pump(stream, null);
}
- });
- thread.start();
- thread.join();
- } catch (Exception ex) {
+ } catch (Exception ex) {
+ exception.set(ex);
+ }
+ });
+ thread.start();
+ thread.join();
+
+ // Handle download thread exception.
+ if (exception.get() != null) {
+ throw exception.get();
}
// Return a stream to the downloaded file/content via our response cache.
URI cachedUri = TiResponseCache.fetchEndpointFollowingRedirects(uri);
if (cachedUri != null) {
- try {
- inputStream = TiResponseCache.openCachedStream(cachedUri);
- } catch (Exception ex) {
- }
+ inputStream = TiResponseCache.openCachedStream(cachedUri);
}
return inputStream;
}
// Convert the given URI to a URL object.
// Note: This object will validate the string and throw an exception if malformed.
- URL url = null;
- try {
- url = new URL(uri.toString());
- } catch (Exception ex) {
- Log.e(TAG, "Failed to parse URL: " + uri.toString(), ex);
- return null;
- }
+ URL url = new URL(uri.toString());
// Attempt to download the file.
URLConnection connection = null;
@@ -215,9 +203,6 @@ public void run()
}
break;
}
- } catch (Exception ex) {
- // Failed to download file/content.
- Log.e(TAG, "Failed to download from: " + uri.toString(), ex);
} finally {
// Close the connection if we don't have a stream to the response body. (Nothing to download.)
if ((inputStream == null) && (connection instanceof HttpURLConnection)) {
@@ -356,7 +341,7 @@ public void run()
// fire a download fail event if we are unable to download
sendMessage(uri, MSG_FIRE_DOWNLOAD_FAILED);
- Log.e(TAG, "Exception downloading from: " + uri, e);
+ Log.e(TAG, "Exception downloading from: " + uri + "\n" + e.getMessage());
}
}
}
diff --git a/tests/Resources/ti.ui.imageview.addontest.js b/tests/Resources/ti.ui.imageview.addontest.js
new file mode 100644
index 00000000000..df8e39f8d94
--- /dev/null
+++ b/tests/Resources/ti.ui.imageview.addontest.js
@@ -0,0 +1,55 @@
+/*
+ * Appcelerator Titanium Mobile
+ * Copyright (c) 2011-Present by Appcelerator, Inc. All Rights Reserved.
+ * Licensed under the terms of the Apache Public License
+ * Please see the LICENSE included with this distribution for details.
+ */
+/* eslint-env mocha */
+/* eslint no-unused-expressions: "off" */
+'use strict';
+
+describe('Titanium.UI.ImageView', function () {
+ var win;
+ this.timeout(5000);
+
+ afterEach(function (done) {
+ if (win) {
+ // If `win` is already closed, we're done.
+ let t = setTimeout(function () {
+ if (win) {
+ win = null;
+ done();
+ }
+ }, 3000);
+
+ win.addEventListener('close', function listener () {
+ clearTimeout(t);
+
+ if (win) {
+ win.removeEventListener('close', listener);
+ }
+ win = null;
+ done();
+ });
+ win.close();
+ } else {
+ win = null;
+ done();
+ }
+ });
+
+ it('image error event', function (finish) {
+ win = Ti.UI.createWindow();
+
+ const img = Ti.UI.createImageView({
+ image: 'https://invalid.host.com/image.jpg'
+ });
+
+ img.addEventListener('error', () => {
+ finish();
+ });
+
+ win.add(img);
+ win.open();
+ });
+});