├── LoadWebImageCache
├── res
│ ├── values
│ │ ├── styles.xml
│ │ └── strings.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ ├── drawable-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_action_search.png
│ ├── drawable-ldpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_action_search.png
│ ├── drawable-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_action_search.png
│ └── layout
│ │ └── activity_main.xml
├── ic_launcher-web.png
├── libs
│ └── android-support-v4.jar
├── gen
│ └── com
│ │ └── technotalkative
│ │ └── loadwebimage
│ │ ├── BuildConfig.java
│ │ └── R.java
├── project.properties
├── src
│ └── com
│ │ └── technotalkative
│ │ └── loadwebimage
│ │ ├── imageutils
│ │ ├── Utils.java
│ │ ├── FileCache.java
│ │ ├── MemoryCache.java
│ │ └── ImageLoader.java
│ │ └── MainActivity.java
├── proguard-project.txt
└── AndroidManifest.xml
├── README.md
├── .gitattributes
└── .gitignore
/LoadWebImageCache/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/LoadWebImageCache/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PareshMayani/Android-LoadWebImageAndCache/HEAD/LoadWebImageCache/ic_launcher-web.png
--------------------------------------------------------------------------------
/LoadWebImageCache/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/LoadWebImageCache/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/LoadWebImageCache/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PareshMayani/Android-LoadWebImageAndCache/HEAD/LoadWebImageCache/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/LoadWebImageCache/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PareshMayani/Android-LoadWebImageAndCache/HEAD/LoadWebImageCache/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/LoadWebImageCache/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PareshMayani/Android-LoadWebImageAndCache/HEAD/LoadWebImageCache/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/LoadWebImageCache/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PareshMayani/Android-LoadWebImageAndCache/HEAD/LoadWebImageCache/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/LoadWebImageCache/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PareshMayani/Android-LoadWebImageAndCache/HEAD/LoadWebImageCache/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/LoadWebImageCache/res/drawable-hdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PareshMayani/Android-LoadWebImageAndCache/HEAD/LoadWebImageCache/res/drawable-hdpi/ic_action_search.png
--------------------------------------------------------------------------------
/LoadWebImageCache/res/drawable-mdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PareshMayani/Android-LoadWebImageAndCache/HEAD/LoadWebImageCache/res/drawable-mdpi/ic_action_search.png
--------------------------------------------------------------------------------
/LoadWebImageCache/res/drawable-xhdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PareshMayani/Android-LoadWebImageAndCache/HEAD/LoadWebImageCache/res/drawable-xhdpi/ic_action_search.png
--------------------------------------------------------------------------------
/LoadWebImageCache/gen/com/technotalkative/loadwebimage/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package com.technotalkative.loadwebimage;
3 |
4 | public final class BuildConfig {
5 | public final static boolean DEBUG = true;
6 | }
--------------------------------------------------------------------------------
/LoadWebImageCache/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | LoadWebImage
4 | Hello world!
5 | Settings
6 | MainActivity
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Android-LoadWebImageAndCache
2 | ============================
3 |
4 | Example/demo on loading image from web and caching
5 | Read more at: http://www.technotalkative.com/android-load-images-from-web-and-caching/
6 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/LoadWebImageCache/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-16
15 |
--------------------------------------------------------------------------------
/LoadWebImageCache/src/com/technotalkative/loadwebimage/imageutils/Utils.java:
--------------------------------------------------------------------------------
1 | package com.technotalkative.loadwebimage.imageutils;
2 |
3 | import java.io.InputStream;
4 | import java.io.OutputStream;
5 |
6 | public class Utils {
7 | public static void CopyStream(InputStream is, OutputStream os)
8 | {
9 | final int buffer_size=1024;
10 | try
11 | {
12 | byte[] bytes=new byte[buffer_size];
13 | for(;;)
14 | {
15 | int count=is.read(bytes, 0, buffer_size);
16 | if(count==-1)
17 | break;
18 | os.write(bytes, 0, count);
19 | }
20 | }
21 | catch(Exception ex){}
22 | }
23 | }
--------------------------------------------------------------------------------
/LoadWebImageCache/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/LoadWebImageCache/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
13 |
14 |
22 |
23 |
--------------------------------------------------------------------------------
/LoadWebImageCache/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/LoadWebImageCache/src/com/technotalkative/loadwebimage/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.technotalkative.loadwebimage;
2 |
3 | import com.technotalkative.loadwebimage.R;
4 | import com.technotalkative.loadwebimage.imageutils.ImageLoader;
5 |
6 | import android.app.Activity;
7 | import android.os.Bundle;
8 | import android.view.View;
9 | import android.widget.ImageView;
10 |
11 | public class MainActivity extends Activity {
12 |
13 | private ImageView imgView;
14 | private ImageLoader imgLoader;
15 | private String strURL = "http://technotalkative.com/android.jpg";
16 |
17 | @Override
18 | public void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_main);
21 |
22 | imgView = (ImageView) findViewById(R.id.imageView1);
23 | imgLoader = new ImageLoader(this);
24 | }
25 |
26 | public void btnLoadImageClick(View v){
27 |
28 | imgLoader.DisplayImage(strURL, imgView);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/LoadWebImageCache/gen/com/technotalkative/loadwebimage/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package com.technotalkative.loadwebimage;
9 |
10 | public final class R {
11 | public static final class attr {
12 | }
13 | public static final class drawable {
14 | public static final int ic_action_search=0x7f020000;
15 | public static final int ic_launcher=0x7f020001;
16 | }
17 | public static final class id {
18 | public static final int btnLoadImage=0x7f060000;
19 | public static final int imageView1=0x7f060001;
20 | }
21 | public static final class layout {
22 | public static final int activity_main=0x7f030000;
23 | }
24 | public static final class string {
25 | public static final int app_name=0x7f040000;
26 | public static final int hello_world=0x7f040001;
27 | public static final int menu_settings=0x7f040002;
28 | public static final int title_activity_main=0x7f040003;
29 | }
30 | public static final class style {
31 | public static final int AppTheme=0x7f050000;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/LoadWebImageCache/src/com/technotalkative/loadwebimage/imageutils/FileCache.java:
--------------------------------------------------------------------------------
1 | package com.technotalkative.loadwebimage.imageutils;
2 |
3 | import java.io.File;
4 | import android.content.Context;
5 |
6 | public class FileCache {
7 |
8 | private File cacheDir;
9 |
10 | public FileCache(Context context){
11 | //Find the dir to save cached images
12 | if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
13 | cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"TTImages_cache");
14 | else
15 | cacheDir=context.getCacheDir();
16 | if(!cacheDir.exists())
17 | cacheDir.mkdirs();
18 | }
19 |
20 | public File getFile(String url){
21 | //I identify images by hashcode. Not a perfect solution, good for the demo.
22 | String filename=String.valueOf(url.hashCode());
23 | //Another possible solution (thanks to grantland)
24 | //String filename = URLEncoder.encode(url);
25 | File f = new File(cacheDir, filename);
26 | return f;
27 |
28 | }
29 |
30 | public void clear(){
31 | File[] files=cacheDir.listFiles();
32 | if(files==null)
33 | return;
34 | for(File f:files)
35 | f.delete();
36 | }
37 |
38 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 | [Dd]ebug/
46 | [Rr]elease/
47 | *_i.c
48 | *_p.c
49 | *.ilk
50 | *.meta
51 | *.obj
52 | *.pch
53 | *.pdb
54 | *.pgc
55 | *.pgd
56 | *.rsp
57 | *.sbr
58 | *.tlb
59 | *.tli
60 | *.tlh
61 | *.tmp
62 | *.vspscc
63 | .builds
64 | *.dotCover
65 |
66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
67 | #packages/
68 |
69 | # Visual C++ cache files
70 | ipch/
71 | *.aps
72 | *.ncb
73 | *.opensdf
74 | *.sdf
75 |
76 | # Visual Studio profiler
77 | *.psess
78 | *.vsp
79 |
80 | # ReSharper is a .NET coding add-in
81 | _ReSharper*
82 |
83 | # Installshield output folder
84 | [Ee]xpress
85 |
86 | # DocProject is a documentation generator add-in
87 | DocProject/buildhelp/
88 | DocProject/Help/*.HxT
89 | DocProject/Help/*.HxC
90 | DocProject/Help/*.hhc
91 | DocProject/Help/*.hhk
92 | DocProject/Help/*.hhp
93 | DocProject/Help/Html2
94 | DocProject/Help/html
95 |
96 | # Click-Once directory
97 | publish
98 |
99 | # Others
100 | [Bb]in
101 | [Oo]bj
102 | sql
103 | TestResults
104 | *.Cache
105 | ClientBin
106 | stylecop.*
107 | ~$*
108 | *.dbmdl
109 | Generated_Code #added for RIA/Silverlight projects
110 |
111 | # Backup & report files from converting an old project file to a newer
112 | # Visual Studio version. Backup files are not needed, because we have git ;-)
113 | _UpgradeReport_Files/
114 | Backup*/
115 | UpgradeLog*.XML
116 |
117 |
118 |
119 | ############
120 | ## Windows
121 | ############
122 |
123 | # Windows image file caches
124 | Thumbs.db
125 |
126 | # Folder config file
127 | Desktop.ini
128 |
129 |
130 | #############
131 | ## Python
132 | #############
133 |
134 | *.py[co]
135 |
136 | # Packages
137 | *.egg
138 | *.egg-info
139 | dist
140 | build
141 | eggs
142 | parts
143 | bin
144 | var
145 | sdist
146 | develop-eggs
147 | .installed.cfg
148 |
149 | # Installer logs
150 | pip-log.txt
151 |
152 | # Unit test / coverage reports
153 | .coverage
154 | .tox
155 |
156 | #Translations
157 | *.mo
158 |
159 | #Mr Developer
160 | .mr.developer.cfg
161 |
162 | # Mac crap
163 | .DS_Store
164 |
--------------------------------------------------------------------------------
/LoadWebImageCache/src/com/technotalkative/loadwebimage/imageutils/MemoryCache.java:
--------------------------------------------------------------------------------
1 | package com.technotalkative.loadwebimage.imageutils;
2 |
3 | import java.util.Collections;
4 | import java.util.Iterator;
5 | import java.util.LinkedHashMap;
6 | import java.util.Map;
7 | import java.util.Map.Entry;
8 | import android.graphics.Bitmap;
9 | import android.util.Log;
10 |
11 | public class MemoryCache {
12 |
13 | private static final String TAG = "MemoryCache";
14 | private Map cache=Collections.synchronizedMap(
15 | new LinkedHashMap(10,1.5f,true));//Last argument true for LRU ordering
16 | private long size=0;//current allocated size
17 | private long limit=1000000;//max memory in bytes
18 |
19 | public MemoryCache(){
20 | //use 25% of available heap size
21 | setLimit(Runtime.getRuntime().maxMemory()/4);
22 | }
23 |
24 | public void setLimit(long new_limit){
25 | limit=new_limit;
26 | Log.i(TAG, "MemoryCache will use up to "+limit/1024./1024.+"MB");
27 | }
28 |
29 | public Bitmap get(String id){
30 | try{
31 | if(!cache.containsKey(id))
32 | return null;
33 | //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78
34 | return cache.get(id);
35 | }catch(NullPointerException ex){
36 | ex.printStackTrace();
37 | return null;
38 | }
39 | }
40 |
41 | public void put(String id, Bitmap bitmap){
42 | try{
43 | if(cache.containsKey(id))
44 | size-=getSizeInBytes(cache.get(id));
45 | cache.put(id, bitmap);
46 | size+=getSizeInBytes(bitmap);
47 | checkSize();
48 | }catch(Throwable th){
49 | th.printStackTrace();
50 | }
51 | }
52 |
53 | private void checkSize() {
54 | Log.i(TAG, "cache size="+size+" length="+cache.size());
55 | if(size>limit){
56 | Iterator> iter=cache.entrySet().iterator();//least recently accessed item will be the first one iterated
57 | while(iter.hasNext()){
58 | Entry entry=iter.next();
59 | size-=getSizeInBytes(entry.getValue());
60 | iter.remove();
61 | if(size<=limit)
62 | break;
63 | }
64 | Log.i(TAG, "Clean cache. New size "+cache.size());
65 | }
66 | }
67 |
68 | public void clear() {
69 | try{
70 | //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78
71 | cache.clear();
72 | size=0;
73 | }catch(NullPointerException ex){
74 | ex.printStackTrace();
75 | }
76 | }
77 |
78 | long getSizeInBytes(Bitmap bitmap) {
79 | if(bitmap==null)
80 | return 0;
81 | return bitmap.getRowBytes() * bitmap.getHeight();
82 | }
83 | }
--------------------------------------------------------------------------------
/LoadWebImageCache/src/com/technotalkative/loadwebimage/imageutils/ImageLoader.java:
--------------------------------------------------------------------------------
1 | package com.technotalkative.loadwebimage.imageutils;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.FileNotFoundException;
6 | import java.io.FileOutputStream;
7 | import java.io.InputStream;
8 | import java.io.OutputStream;
9 | import java.net.HttpURLConnection;
10 | import java.net.URL;
11 | import java.util.Collections;
12 | import java.util.Map;
13 | import java.util.WeakHashMap;
14 | import java.util.concurrent.ExecutorService;
15 | import java.util.concurrent.Executors;
16 |
17 | import android.app.Activity;
18 | import android.content.Context;
19 | import android.graphics.Bitmap;
20 | import android.graphics.BitmapFactory;
21 | import android.widget.ImageView;
22 |
23 | import com.technotalkative.loadwebimage.R;
24 |
25 | public class ImageLoader {
26 |
27 | MemoryCache memoryCache=new MemoryCache();
28 | FileCache fileCache;
29 | private Map imageViews=Collections.synchronizedMap(new WeakHashMap());
30 | ExecutorService executorService;
31 |
32 | public ImageLoader(Context context){
33 | fileCache=new FileCache(context);
34 | executorService=Executors.newFixedThreadPool(5);
35 | }
36 |
37 | final int stub_id=R.drawable.ic_launcher;
38 | public void DisplayImage(String url, ImageView imageView)
39 | {
40 | imageViews.put(imageView, url);
41 | Bitmap bitmap=memoryCache.get(url);
42 | if(bitmap!=null)
43 | imageView.setImageBitmap(bitmap);
44 | else
45 | {
46 | queuePhoto(url, imageView);
47 | imageView.setImageResource(stub_id);
48 | }
49 | }
50 |
51 | private void queuePhoto(String url, ImageView imageView)
52 | {
53 | PhotoToLoad p=new PhotoToLoad(url, imageView);
54 | executorService.submit(new PhotosLoader(p));
55 | }
56 |
57 | private Bitmap getBitmap(String url)
58 | {
59 | File f=fileCache.getFile(url);
60 |
61 | //from SD cache
62 | Bitmap b = decodeFile(f);
63 | if(b!=null)
64 | return b;
65 |
66 | //from web
67 | try {
68 | Bitmap bitmap=null;
69 | URL imageUrl = new URL(url);
70 | HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
71 | conn.setConnectTimeout(30000);
72 | conn.setReadTimeout(30000);
73 | conn.setInstanceFollowRedirects(true);
74 | InputStream is=conn.getInputStream();
75 | OutputStream os = new FileOutputStream(f);
76 | Utils.CopyStream(is, os);
77 | os.close();
78 | bitmap = decodeFile(f);
79 | return bitmap;
80 | } catch (Throwable ex){
81 | ex.printStackTrace();
82 | if(ex instanceof OutOfMemoryError)
83 | memoryCache.clear();
84 | return null;
85 | }
86 | }
87 |
88 | //decodes image and scales it to reduce memory consumption
89 | private Bitmap decodeFile(File f){
90 | try {
91 | //decode image size
92 | BitmapFactory.Options o = new BitmapFactory.Options();
93 | o.inJustDecodeBounds = true;
94 | BitmapFactory.decodeStream(new FileInputStream(f),null,o);
95 |
96 | //Find the correct scale value. It should be the power of 2.
97 | final int REQUIRED_SIZE=70;
98 | int width_tmp=o.outWidth, height_tmp=o.outHeight;
99 | int scale=1;
100 | while(true){
101 | if(width_tmp/2