Put a lock on image loading.

This commit is contained in:
Pierre 2018-05-21 09:29:22 +02:00
parent 98713def11
commit 92b2d846bb
2 changed files with 53 additions and 10 deletions

View File

@ -24,17 +24,24 @@ class ImageLoadApplyRunnable implements Runnable {
*/
private ImageView imageView;
/**
* Object to notify when the image has been posted
*/
private Object obj = null;
/**
* Construct the class
*
* @param imageView The target image view
* @param bitmap The bitmap to apply
* @param obj Object to notify once the image has been applied
*/
ImageLoadApplyRunnable(ImageView imageView, Bitmap bitmap){
ImageLoadApplyRunnable(ImageView imageView, Bitmap bitmap, Object obj){
//Save the values
this.bitmap = bitmap;
this.imageView = imageView;
this.obj = obj;
}
/**
@ -46,5 +53,11 @@ class ImageLoadApplyRunnable implements Runnable {
//Apply the image
imageView.setImageBitmap(bitmap);
synchronized (obj){
//Notify
obj.notifyAll();
}
}
}

View File

@ -11,6 +11,7 @@ import org.communiquons.android.comunic.client.data.utils.ImageLoadUtils;
import java.io.File;
import java.io.FileInputStream;
import java.util.concurrent.locks.ReentrantLock;
/**
* Image loading runnable
@ -29,6 +30,11 @@ public class ImageLoadRunnable implements Runnable {
*/
private static final String TAG = "ImageLoadRunnable";
/**
* Image load lock
*/
public static ReentrantLock ImageLoadLock = null;
/**
* An array map with all the pending images associated with their URLs
*/
@ -63,6 +69,10 @@ public class ImageLoadRunnable implements Runnable {
*/
public ImageLoadRunnable(Context context, ImageView imageView, String url){
if(ImageLoadLock == null)
ImageLoadLock = new ReentrantLock();
//Check if the list of pending operations has to be initialized or not
if(pendingOperation == null)
pendingOperation = new ArrayMap<>();
@ -83,19 +93,18 @@ public class ImageLoadRunnable implements Runnable {
String filename = ImageLoadUtils.IMAGE_CACHE_DIRECTORY + ImageLoadUtils.get_file_name(url);
//Create file object
file = new File(mContext.getCacheDir(),filename);
file = new File(mContext.getCacheDir(), filename);
//Check no thread is already running for the following image
if(!pendingOperation.containsKey(url)){
if (!pendingOperation.containsKey(url)) {
//Check if a file exist or not
if(file.exists()){
if (file.exists()) {
//Then the file can be loaded in a bitmap
load_image();
safe_load_image();
return;
}
else {
} else {
//Create the thread and start it
Thread thread = new Thread(new ImageDownloadRunnable(url, file));
@ -108,12 +117,12 @@ public class ImageLoadRunnable implements Runnable {
Thread operation = pendingOperation.get(url);
//If we couldn't get the thread, this is an error
if(operation == null){
if (operation == null) {
Log.e("ImageLoadManagerRunnabl", "run : Couldn't get thread !");
return;
}
if(operation.isAlive()) {
if (operation.isAlive()) {
try {
//Wait for the thread to finish
operation.join();
@ -127,8 +136,21 @@ public class ImageLoadRunnable implements Runnable {
//Remove the thread from the pending list
pendingOperation.remove(url);
safe_load_image();
}
/**
* Load images safely
*/
private void safe_load_image(){
Log.v(TAG, "Before lock");
ImageLoadLock.lock();
//Load the image
load_image();
ImageLoadLock.unlock();
}
/**
@ -160,11 +182,19 @@ public class ImageLoadRunnable implements Runnable {
//Delete file
file.delete();
return;
}
//Apply the bitmap on the image view (register operation)
imageView.post(new ImageLoadApplyRunnable(imageView, bitmap));
Object obj = new Object();
synchronized (obj){
imageView.post(new ImageLoadApplyRunnable(imageView, bitmap, obj));
Log.v(TAG, "Locking for " + url);
obj.wait(1000); //Wait for the image to be applied
Log.v(TAG, "Unlocking " + url);
}
} catch (Exception e){
e.printStackTrace();