package net.photonmed.imagescrubber.app.utils.threading;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import com.squareup.okhttp.OkHttpClient;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
/**
* Thread manager service that will manage concurrent image parser thread manager
*/
public class ImageParserThreadManager {
public static final int MAX_MEMORY = (int)(Runtime.getRuntime().maxMemory() / 1024); //store in kb
public final int cacheSize = ImageParserThreadManager.MAX_MEMORY/ 2;
public static final String IMAGE_PARSING_COMPLETE = "net.photonmed.android.imageparser";
public static final String IMAGE_PARSED = "net.photonmed.android.imageparsed";
private static final int CONCURRENT_MAX = 4;
private static ImageParserThreadManager manager;
private List<ImageParserRunnable> runningParsers;
private List<ImageParserRunnable> parsersToRun;
private Map<Integer, byte[]> bitmapMap;
private ThreadPoolExecutor executor;
private Context context;
private OkHttpClient client;
public OkHttpClient getClient() {
return client;
}
public HashMap<Integer, byte[]> getBitmapBytes() {
HashMap<Integer, byte[]> copyOf = new HashMap<Integer, byte[]>(bitmapMap);
bitmapMap.clear();
return copyOf;
}
public void emptyBitmapBytes() {
bitmapMap.clear();
}
private ImageParserThreadManager(Context context) {
this.runningParsers = Collections.synchronizedList(new ArrayList<ImageParserRunnable>());
this.parsersToRun = Collections.synchronizedList(new ArrayList<ImageParserRunnable>());
this.executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
this.context = context;
this.bitmapMap = Collections.synchronizedMap(new HashMap<Integer, byte[]>());
this.client = new OkHttpClient();
}
public void addTasksToRun(List<String> tasks) {
//TODO: Need to optimize this loop, seems micro, but we're dealing with a startup routine with a large collection
int i = 0;
for (String task : tasks) {
ImageParserRunnable runnable = new ImageParserRunnable(task, i);
i++;
parsersToRun.add(runnable);
}
}
public void removeTaskToRun(ImageParserRunnable task) {
parsersToRun.remove(task);
}
public void removeRunningTask(ImageParserRunnable task, boolean success, byte[] bitmap) {
runningParsers.remove(task);
if (success) {
removeTaskToRun(task);
bitmapMap.put(task.getIndexNumber(), bitmap);
Intent intent = new Intent(IMAGE_PARSED);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
if (runningParsers.size() == 0) {
executeTasks();
}
}
public void executeTasks() {
if (parsersToRun.size() == 0) {
Intent intent = new Intent(IMAGE_PARSING_COMPLETE);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
return;
}
for (int i = 0; (i <= ImageParserThreadManager.CONCURRENT_MAX || i > parsersToRun.size()); i++) {
ImageParserRunnable runnable = parsersToRun.get(i);
runningParsers.add(runnable);
try {
executor.execute(runnable);
} catch (RejectedExecutionException ex) {
removeRunningTask(runnable, false, null);
}
}
}
public static ImageParserThreadManager getInstance(Context context) {
if (manager == null) {
manager = new ImageParserThreadManager(context.getApplicationContext());
}
return manager;
}
}