Android 4.0 Http缓存机制

来源:互联网 发布:手机能注册淘宝店吗 编辑:程序博客网 时间:2024/06/03 21:05

Android早已经在4.0版本添加了缓存支持,以下内容是对Android官方文档的一个总结。

(一)  HttpResponseCache 类在Android 4.0 版本添加支持,支持 HttpURLConnection HttpsURLConnection,但不支持DefaultHttpClientAndroidHttpClient

HttpResponseCache的好处:

1.明显一点节约电,减少了网络请求。

2.开发者不用自己在去写cache机制了。

3.最根本的一点就是,如果开发者在开发中不是使用的HttpClient, HttpDefaultClient...,而是用 HttpURLConnection的话,你根本不用改本來的 Code

 

(1).在程序开启的时候设定需要缓存,并设定缓存目录和缓存文件大小,例如:(最好把缓存目录设定在外部存储)

 

 static volatile Object cache;private static final Object lock = new Object();private static final int MIN_DISK_CACHE_SIZE = 5 * 1024 * 1024; // 5MBprivate static final int MAX_DISK_CACHE_SIZE = 50 * 1024 * 1024; // 50MBif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){installCacheIfNeeded(context);}private static void installCacheIfNeeded(Context context){// DCL + volatile should be safe after Java 5.if (cache == null){try{synchronized (lock){if (cache == null){cache = install(context);}}}catch (IOException ignored){}}}public void install(Context context){File cacheDir = createDefaultCacheDir(context);HttpResponseCache cache = HttpResponseCache.getInstalled();if (cache == null){long maxSize = calculateDiskCacheSize(cacheDir);cache = HttpResponseCache.install(cacheDir, maxSize);}}static File createDefaultCacheDir(Context context){File cache = new File(context.getApplicationContext().getCacheDir(), "Cache_Name");if (!cache.exists()){// noinspection ResultOfMethodCallIgnoredcache.mkdirs();}return cache;}static long calculateDiskCacheSize(File dir){long size = MIN_DISK_CACHE_SIZE;try{StatFs statFs = new StatFs(dir.getAbsolutePath());long available = ((long) statFs.getBlockCount()) * statFs.getBlockSize();// Target 2% of the total space.size = available / 50;}catch (IllegalArgumentException ignored){}// Bound inside min/max size for disk cache.return Math.max(Math.min(size, MAX_DISK_CACHE_SIZE), MIN_DISK_CACHE_SIZE);}


 

(2).根据请求需要设置缓存

    a.例如点击“刷新”按钮,或者手动刷新,这时候要强制刷新,就需要添加“no-cache”指令
connection.addRequestProperty("Cache-Control","no-cache");

    b.如果只需要强制缓存的响应由服务器进行验证,使用更高效的“max-age=0”指令来代替:
connection.addRequestProperty("Cache-Control","max-age=0");

       c. 有时候,你只想加载缓存数据,你需要设定“ only-if-cached”指令
try{         connection.addRequestProperty("Cache-Control","only-if-cached");         InputStream cached = connection.getInputStream();         // the resource was cached! show it     catch(FileNotFoundException e){         // the resource was not cached     } }

   d.你还可以设定缓存的有效时间
 
int maxStale =60*60*24*28;// tolerate 4-weeks stale         
connection.addRequestProperty("Cache-Control","max-stale="+ maxStale);

个人理解会将http请求放在本地,如果有相同的请求,就不会再次调用网络请求,直接得到本地请求响应的值

[java] view plaincopy
  1. public class HttpCacheApplication extends Application {  
  2.     @Override  
  3.     public void onCreate() {  
  4.         super.onCreate();  
  5.         new Thread() {  
  6.             @Override  
  7.             public void run() {  
  8.                 enableHttpResponseCache();  
  9.             }  
  10.         }.start();  
  11.     }  
  12.   
  13.     private void enableHttpResponseCache() {  
  14.         try {  
  15.             long httpCacheSize = 10 * 1024 * 1024;// 10M  
  16.             File httpCacheDir = new File(getCacheDir(), "http");  
  17.             Class.forName("android.net.http.HttpResponseCache")  
  18.                     .getMethod("install", File.classlong.class)  
  19.                     .invoke(null, httpCacheDir, httpCacheSize);  
  20.         } catch (Exception e) {  
  21.             Log.e("===>", e.getMessage(), e);  
  22.         }  
  23.     }  
  24.   
  25. }  


接下来我们来看看HttpUrlConnection是怎么处理的,怎么缓存的。

[java] view plaincopy
  1. public class MainActivity extends Activity {  
  2.   
  3.     private final String TAG = getClass().getSimpleName();  
  4.     ImageView img;  
  5.     Button msg;  
  6.     TextView tv;  
  7.     @Override  
  8.     public void onCreate(Bundle savedInstanceState) {  
  9.         super.onCreate(savedInstanceState);  
  10.         setContentView(R.layout.activity_main);  
  11.   
  12.         img = (ImageView) findViewById(R.id.imageView1);  
  13.         tv = (TextView)findViewById(R.id.textView1);  
  14.         msg = (Button) findViewById(R.id.button1);  
  15.         msg.setOnClickListener(new OnClickListener() {  
  16.             @Override  
  17.             public void onClick(View v) {  
  18.                 new InternetTask().execute();  
  19.             }  
  20.         });  
  21.         findViewById(R.id.button2).setOnClickListener(new OnClickListener() {  
  22.               
  23.             @Override  
  24.             public void onClick(View v) {  
  25.                 MainActivity.this.finish();  
  26.             }  
  27.         });  
  28.     }  
  29.   
  30.     class InternetTask extends AsyncTask<String, String, Boolean> {  
  31.         Bitmap bitmap;  
  32.         String jsonStr;  
  33.   
  34.         @Override  
  35.         protected void onPostExecute(Boolean result) {  
  36.             super.onPostExecute(result);  
  37.             img.setImageBitmap(bitmap);  
  38.             tv.setText(jsonStr);  
  39.         }  
  40.   
  41.         @Override  
  42.         protected Boolean doInBackground(String... params) {  
  43.             // Test download image  
  44.             try {  
  45.                 URL url = new URL("http://news.baidu.com/resource/img/logo_news_137_46.png");  
  46.                 HttpURLConnection conn = (HttpURLConnection) (url  
  47.                         .openConnection());  
  48.                 conn.connect();  
  49.                 InputStream is = conn.getInputStream();  
  50.                 BitmapFactory.Options ops = new BitmapFactory.Options();  
  51.                 bitmap = BitmapFactory.decodeStream(is, null, ops);  
  52.                 is.close();  
  53.                 conn.disconnect();   
  54.             } catch (Exception e) {  
  55.                 Log.e(TAG, e.getMessage(), e);  
  56.             }  
  57.   
  58.             // Test download JSON data  
  59.             try {  
  60.                 URL url = new URL("http://www.baidu.com/");  
  61.                 HttpURLConnection conn = (HttpURLConnection) (url  
  62.                         .openConnection());  
  63.                 conn.connect();    
  64.                 BufferedReader reader = new BufferedReader(  
  65.                         new InputStreamReader(conn.getInputStream(), "UTF-8"));  
  66.                 jsonStr = reader.readLine();  
  67.                 InputStream is = conn.getInputStream();  
  68.                 is.close();  
  69.                 conn.disconnect();  
  70.             } catch (Exception e) {  
  71.                 Log.e(TAG, e.getMessage(), e);  
  72.             }  
  73.             return true;  
  74.         }  
  75.   
  76.     }  
  77.   
  78. }  

我们看下效果:

看下缓存文件,每个文件会产生两个文件,一个是数据文件,一个是http header 信息

 

 

0 0
原创粉丝点击