Android 4.0 Http缓存机制

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; // 5MB
	private static final int MAX_DISK_CACHE_SIZE = 50 * 1024 * 1024; // 50MB
	
	if (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 ResultOfMethodCallIgnored
			cache.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请求放在本地,如果有相同的请求,就不会再次调用网络请求,直接得到本地请求响应的值

  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是怎么处理的,怎么缓存的。

  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
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值