This repository has been archived by the owner on Nov 22, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d740b80
commit 3946bd4
Showing
1 changed file
with
193 additions
and
1 deletion.
There are no files selected for viewing
194 changes: 193 additions & 1 deletion
194
src/src/main/java/agency/techstar/imageloader/ImageLoader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,200 @@ | ||
package agency.techstar.imageloader; | ||
|
||
import android.content.Context; | ||
import android.graphics.Bitmap; | ||
import android.graphics.BitmapFactory; | ||
import android.graphics.Color; | ||
import android.os.Handler; | ||
import android.widget.ImageView; | ||
|
||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.FileNotFoundException; | ||
import java.io.FileOutputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
import java.net.HttpURLConnection; | ||
import java.net.URL; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
import java.util.WeakHashMap; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
|
||
/** | ||
* Created by turtuvshin on 10/14/17. | ||
*/ | ||
|
||
public class ImageLoader { | ||
} | ||
|
||
MemoryCache memoryCache=new MemoryCache(); | ||
FileCache fileCache; | ||
private Map<ImageView, String> imageViews= Collections.synchronizedMap(new WeakHashMap<ImageView, String>()); | ||
ExecutorService executorService; | ||
Handler handler=new Handler(); | ||
|
||
public ImageLoader(Context context){ | ||
fileCache=new FileCache(context); | ||
executorService= Executors.newFixedThreadPool(5); | ||
} | ||
|
||
public void DisplayImage(String url, ImageView imageView) | ||
{ | ||
imageViews.put(imageView, url); | ||
Bitmap bitmap=memoryCache.get(url); | ||
if(bitmap!=null) | ||
imageView.setImageBitmap(bitmap); | ||
else | ||
{ | ||
queuePhoto(url, imageView); | ||
} | ||
} | ||
|
||
private void queuePhoto(String url, ImageView imageView) | ||
{ | ||
PhotoToLoad p=new PhotoToLoad(url, imageView); | ||
executorService.submit(new PhotosLoader(p)); | ||
} | ||
|
||
private Bitmap getBitmap(String url) | ||
{ | ||
File f=fileCache.getFile(url); | ||
|
||
Bitmap b = decodeFile(f); | ||
if(b!=null) | ||
return b; | ||
|
||
try { | ||
Bitmap bitmap=null; | ||
URL imageUrl = new URL(url); | ||
HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection(); | ||
conn.setConnectTimeout(30000); | ||
conn.setReadTimeout(30000); | ||
conn.setInstanceFollowRedirects(true); | ||
InputStream is=conn.getInputStream(); | ||
OutputStream os = new FileOutputStream(f); | ||
copyStream(is, os); | ||
os.close(); | ||
conn.disconnect(); | ||
bitmap = decodeFile(f); | ||
return bitmap; | ||
} catch (Throwable ex){ | ||
ex.printStackTrace(); | ||
if(ex instanceof OutOfMemoryError) | ||
memoryCache.clear(); | ||
return null; | ||
} | ||
} | ||
|
||
private Bitmap decodeFile(File f){ | ||
try { | ||
BitmapFactory.Options o = new BitmapFactory.Options(); | ||
o.inJustDecodeBounds = true; | ||
FileInputStream stream1=new FileInputStream(f); | ||
BitmapFactory.decodeStream(stream1,null,o); | ||
stream1.close(); | ||
|
||
final int REQUIRED_SIZE=140; | ||
int width_tmp=o.outWidth, height_tmp=o.outHeight; | ||
int scale=1; | ||
while(true){ | ||
if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) | ||
break; | ||
width_tmp/=2; | ||
height_tmp/=2; | ||
scale*=2; | ||
} | ||
|
||
BitmapFactory.Options o2 = new BitmapFactory.Options(); | ||
o2.inSampleSize=scale; | ||
FileInputStream stream2=new FileInputStream(f); | ||
Bitmap bitmap=BitmapFactory.decodeStream(stream2, null, o2); | ||
stream2.close(); | ||
return bitmap; | ||
} catch (FileNotFoundException e) { | ||
} | ||
catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
return null; | ||
} | ||
|
||
private class PhotoToLoad | ||
{ | ||
public String url; | ||
public ImageView imageView; | ||
public PhotoToLoad(String u, ImageView i){ | ||
url=u; | ||
imageView=i; | ||
} | ||
} | ||
|
||
class PhotosLoader implements Runnable { | ||
PhotoToLoad photoToLoad; | ||
PhotosLoader(PhotoToLoad photoToLoad){ | ||
this.photoToLoad=photoToLoad; | ||
} | ||
|
||
@Override | ||
public void run() { | ||
try{ | ||
if(imageViewReused(photoToLoad)) | ||
return; | ||
Bitmap bmp=getBitmap(photoToLoad.url); | ||
memoryCache.put(photoToLoad.url, bmp); | ||
if(imageViewReused(photoToLoad)) | ||
return; | ||
BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad); | ||
handler.post(bd); | ||
}catch(Throwable th){ | ||
th.printStackTrace(); | ||
} | ||
} | ||
} | ||
|
||
boolean imageViewReused(PhotoToLoad photoToLoad){ | ||
String tag=imageViews.get(photoToLoad.imageView); | ||
if(tag==null || !tag.equals(photoToLoad.url)) | ||
return true; | ||
return false; | ||
} | ||
|
||
class BitmapDisplayer implements Runnable | ||
{ | ||
Bitmap bitmap; | ||
PhotoToLoad photoToLoad; | ||
public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;} | ||
public void run() | ||
{ | ||
if(imageViewReused(photoToLoad)) | ||
return; | ||
if(bitmap!=null) | ||
photoToLoad.imageView.setImageBitmap(bitmap); | ||
else | ||
photoToLoad.imageView.setBackgroundColor(Color.parseColor("#00000000")); | ||
} | ||
} | ||
|
||
public void clearCache() { | ||
memoryCache.clear(); | ||
fileCache.clear(); | ||
} | ||
|
||
public static void copyStream(InputStream is, OutputStream os) | ||
{ | ||
final int buffer_size=1024; | ||
try | ||
{ | ||
byte[] bytes=new byte[buffer_size]; | ||
for(;;) | ||
{ | ||
int count=is.read(bytes, 0, buffer_size); | ||
if(count==-1) | ||
break; | ||
os.write(bytes, 0, count); | ||
} | ||
} | ||
catch(Exception ex){} | ||
} | ||
} |