在网络通畅的情况下,获取网络数据显示是非常容易的。但是当网络不通畅的时候,或者说是完全没有网络时该怎么办呢?不可能直接给用户一个白板界面吧。
通常的处理方式是将某些界面的数据写入缓存,获取数据时首先查看缓存文件里面是已经有这些数据,有则直接用,没有的话在去连接网络获取数据并写入缓存,比方说新闻类APP一般情况下都是将第一页的数据写入缓存。
缓存的位置的话就是看情况而定了,一般情况都是写入文件缓存。就是data-》data->下的对应应用程序的文件中。这个文件会随程序的卸载而释放控件。
下面就是实际Demo:
首先是缓存类:里面就是将数据读入文件和写入文件操作:缓存文件名采用了给定的url地址中的一些字符来作为标识。
package com.scxh.android1503.http.cache;
import com.scxh.android1503.util.Logs;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class ConfigCache {
public static String mSdcardDataDir = "";
public static String getUrlCache(String url) {
if (url == null) {
return null;
}
Logs.e("读缓存数据");
String result = null;
File file = new File(mSdcardDataDir + "/" + getCacheDecodeString(url));
if (file.exists() && file.isFile()) {
result = readTextFile(file);
}
return result;
}
public static void setUrlCache(String data, String url) {
File file = new File(mSdcardDataDir + "/" + getCacheDecodeString(url));
//创建缓存数据到磁盘,就是创建文件
Logs.e("写缓存数据");
writeTextFile(file, data);
}
public static String getCacheDecodeString(String url) {
//1. 处理特殊字符
//2. 去除后缀名带来的文件浏览器的视图凌乱(特别是图片更需要如此类似处理,否则有的手机打开图库,全是我们的缓存图片)
if (url != null) {
return url.replaceAll("[.:/,%?&=]", "+").replaceAll("[+]+", "+");
}
return null;
}
public static void writeTextFile(File file, String data) {
FileOutputStream os = null;
try {
os = new FileOutputStream(file);
os.write(data.getBytes("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static String readTextFile(File file) {
FileInputStream instream = null;
StringBuilder sb = null;
try {
instream = new FileInputStream(file);
InputStreamReader inputreader = new InputStreamReader(instream);
BufferedReader buffreader = new BufferedReader(inputreader);
String line;
sb = new StringBuilder();
//分行读取
while ((line = buffreader.readLine()) != null) {
sb.append(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (instream != null) {
try {
instream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
}
之后还有一个测试Activity:给了一个Http地址,返回的是JSON字符串。写入缓存的也是这些JSON字符数据。xml布局是一个按钮和一个显示JSON数据的TextView控件。这里就没有贴出了。
package com.scxh.android1503.http.cache;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.TextHttpResponseHandler;
import com.scxh.android1503.R;
import com.scxh.android1503.util.Logs;
import cz.msebera.android.httpclient.Header;
public class HttpCacheActivity extends Activity {
private String CONFIG_URL = "http://c.m.163.com/nc/article/headline/T1348647909107/0-20.html";
private TextView mCacheTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_http_cache_layout);
mCacheTxt = (TextView) findViewById(R.id.cache_textview);
ConfigCache.mSdcardDataDir = getFilesDir().getAbsolutePath();
}
public void onCacheClickLisenter(View v){
getConfig();
}
void getConfig() {
//首先尝试读取缓存
String cacheConfigString = ConfigCache.getUrlCache(CONFIG_URL);
//根据结果判定是读取缓存,还是重新读取
if (cacheConfigString != null) {
<span style="white-space:pre"> </span> toast.makeText(this,"文件取数据",Toast.LENGTH_SHORT).show();
showConfig(cacheConfigString);
} else {
//如果缓存结果是空,说明需要重新加载
//缓存为空的原因可能是1.无缓存;2. 缓存过期;3.读取缓存出错
AsyncHttpClient client = new AsyncHttpClient();
client.get(CONFIG_URL, new TextHttpResponseHandler() {
@Override
public void onFailure(int i, Header[] headers, String s, Throwable throwable) {
//根据失败原因,考虑是显示加载失败,还是再读取缓存
Toast.makeText(HttpCacheActivity.this, "连接网络出错", Toast.LENGTH_SHORT).show();
}
@Override
public void onSuccess(int i, Header[] headers, String s) {
//成功下载,则保存到本地作为后面缓存文件
ConfigCache.setUrlCache(s, CONFIG_URL);
//后面可以是UI更新,仅供参考
showConfig(s);
<pre name="code" class="java"> toast.makeText(this,"文件取数据",Toast.LENGTH_SHORT).show();
} }); } } public void showConfig(String msg){ Logs.e(msg); mCacheTxt.setText(msg); }}
最后就呈现了这样的结果。第一次从网络获取数据之后。第二次就直接从文件中读取数据。当没有网络的情况下也是从文件中读取数据。
当然也不是什么数据都要缓存起来,缓存某一些数据即可达到运行流畅和提示网络连接的作用即可。