Skip to content

Commit

Permalink
fix(android): refactor TiDownloadManager concurrency handling
Browse files Browse the repository at this point in the history
  • Loading branch information
garymathews committed May 7, 2021
1 parent 7114e2a commit 6403c9c
Showing 1 changed file with 40 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;
Expand All @@ -42,8 +45,9 @@ public class TiDownloadManager implements Handler.Callback
protected static TiDownloadManager _instance;
public static final int THREAD_POOL_SIZE = 2;

protected HashMap<String, ArrayList<SoftReference<TiDownloadListener>>> listeners = new HashMap<>();
protected ArrayList<String> downloadingURIs = new ArrayList<>();
protected Map<String, List<SoftReference<TiDownloadListener>>> listeners
= Collections.synchronizedMap(new HashMap<>());
protected List<String> downloadingURIs = Collections.synchronizedList(new ArrayList<>());
protected ExecutorService threadPool;
protected Handler handler;

Expand Down Expand Up @@ -242,42 +246,44 @@ private void sendMessage(URI uri, int what)
protected void startDownload(URI uri, TiDownloadListener listener)
{
String key = uri.toString();
ArrayList<SoftReference<TiDownloadListener>> listenerList = null;
synchronized (listeners)
List<SoftReference<TiDownloadListener>> listenerList = listeners.get(key);

if (listenerList == null) {
listenerList = Collections.synchronizedList(new ArrayList<>());
listeners.put(key, listenerList);
}

synchronized (listenerList)
{
if (!listeners.containsKey(key)) {
listenerList = new ArrayList<SoftReference<TiDownloadListener>>();
listeners.put(key, listenerList);
} else {
listenerList = listeners.get(key);
}

// We only allow a listener once per URI
for (SoftReference<TiDownloadListener> l : listenerList) {
if (l.get() == listener) {
return;
}
}
listenerList.add(new SoftReference<TiDownloadListener>(listener));
listenerList.add(new SoftReference<>(listener));
}
synchronized (downloadingURIs)
{
if (!downloadingURIs.contains(key)) {
downloadingURIs.add(key);
threadPool.execute(new DownloadJob(uri));
}

if (downloadingURIs.add(key)) {
threadPool.execute(new DownloadJob(uri));
}
}

protected void handleFireDownloadMessage(URI uri, int what)
{
ArrayList<SoftReference<TiDownloadListener>> listenerList;
synchronized (listeners)
{
listenerList = listeners.get(uri.toString());
List<SoftReference<TiDownloadListener>> listenerList = listeners.get(uri.toString());

if (listenerList == null) {
return;
}
if (listenerList != null) {
for (Iterator<SoftReference<TiDownloadListener>> i = listenerList.iterator(); i.hasNext();) {

synchronized (listenerList)
{

for (Iterator<SoftReference<TiDownloadListener>> i = listenerList.iterator(); i.hasNext(); ) {
TiDownloadListener downloadListener = i.next().get();

if (downloadListener != null) {
if (what == MSG_FIRE_DOWNLOAD_FINISHED) {
downloadListener.downloadTaskFinished(uri);
Expand Down Expand Up @@ -310,20 +316,20 @@ public void run()
}
}

synchronized (downloadingURIs)
{
downloadingURIs.remove(uri.toString());
}
downloadingURIs.remove(uri.toString());

// If there is additional background task, run it here.
synchronized (listeners)
{
ArrayList<SoftReference<TiDownloadListener>> listenerList;
listenerList = listeners.get(uri.toString());

if (listenerList != null) {
for (Iterator<SoftReference<TiDownloadListener>> i = listenerList.iterator(); i.hasNext();) {
List<SoftReference<TiDownloadListener>> listenerList = listeners.get(uri.toString());

if (listenerList != null) {

synchronized (listenerList)
{

for (Iterator<SoftReference<TiDownloadListener>> i = listenerList.iterator(); i.hasNext(); ) {
TiDownloadListener downloadListener = i.next().get();

if (downloadListener != null) {
downloadListener.postDownload(uri);
}
Expand All @@ -334,10 +340,7 @@ public void run()
sendMessage(uri, MSG_FIRE_DOWNLOAD_FINISHED);
} catch (Exception e) {

synchronized (downloadingURIs)
{
downloadingURIs.remove(uri.toString());
}
downloadingURIs.remove(uri.toString());

// fire a download fail event if we are unable to download
sendMessage(uri, MSG_FIRE_DOWNLOAD_FAILED);
Expand Down

0 comments on commit 6403c9c

Please sign in to comment.