//1.基础类

public abstract class BaseProtocol<T>{

/**
* 加载appinfo信息
* @param index
* @return
*/
public T load(int index) {
try {
String json = loadLocal(index);
if (json == null) {
json = loadServer(index);
if (json != null)
save2Local(index, json);
}
if (json != null) {
return paserJson(json);
}
} catch (HttpException e) {
e.printStackTrace();
}
return null;
}

/**
* 根据时间戳来读取本地缓存
* @param index
* @return
*/
private String loadLocal(int index) {
BufferedReader br = null;
try {
File dir = FileUtil.getCacheDir();
// getParams() 为了区分包名
File file = new File(dir, getKey() +"_" + index + getParams());
FileReader fr = new FileReader(file);
br = new BufferedReader(fr);
String timeStr = br.readLine();
if (System.currentTimeMillis() > Long.parseLong(timeStr)) {
return null;
} else {
String str = "";
StringWriter sw = new StringWriter();
while ((str = br.readLine()) != null) {
sw.write(str);
}
return sw.toString();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}

/**
* 加载服务器数据
* @param index
* @return
* @throws HttpException
*/
private String loadServer(int index) throws HttpException {
HttpResult httpResult = HttpHelper.get(HttpHelper.URL + getKey() +"?index=" + index + getParams());
return httpResult !=null ? httpResult.toString() : null;
}

/**
* 给地址添加请求参数
* @return
*/
public String getParams() {
return "";
}

private void save2Local(int index, String json) {
BufferedWriter bw = null;
try {
File dir = FileUtil.getCacheDir();
File file = new File(dir, getKey() + "_" + index + getParams());
FileWriter fw = new FileWriter(file);
bw = new BufferedWriter(fw);
long time = (int) (System.currentTimeMillis() + 1000 * 10);
bw.write(time + "");
bw.newLine();
bw.write(json);
bw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

/**
* 返回请求的文件夹名称
* @return
*/
public abstract String getKey();

/**
* 解析json数据
* @param json
* @return
*/
public abstract T paserJson(String json);
}

//2.实现类

public class TopProtocol extends BaseProtocol<List<String>> {

@Override
public String getKey() {
return "hot";
}

@Override
public List<String> paserJson(String json) {
List<String> list = new ArrayList<String>();
try {
JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {
//JSONObject jsonObject = jsonArray.getJSONObject(i);
//String hot = jsonObject.getString(")
String hot = jsonArray.getString(i);
list.add(hot);
}
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}

}

//3.HttpHelper .java 与HttpResult.java

public class HttpHelper {

public static final String URL = "http://127.0.0.1:8090/";

/** get请求,获取返回字符串内容 */
public static HttpResult get(String url) {
HttpGet httpGet = new HttpGet(url);
return execute(url, httpGet);
}

/** post请求,获取返回字符串内容 */
public static HttpResult post(String url, byte[] bytes) {
HttpPost httpPost = new HttpPost(url);
ByteArrayEntity byteArrayEntity = new ByteArrayEntity(bytes);
httpPost.setEntity(byteArrayEntity);
return execute(url, httpPost);
}

/** 下载 */
public static HttpResult download(String url) {
HttpGet httpGet = new HttpGet(url);
return execute(url, httpGet);
}

/** 执行网络访问 */
private static HttpResult execute(String url, HttpRequestBase requestBase) {
boolean isHttps = url.startsWith("https://");//判断是否需要采用https
AbstractHttpClient httpClient = HttpClientFactory.create(isHttps);
HttpContext httpContext = new SyncBasicHttpContext(new BasicHttpContext());
HttpRequestRetryHandler retryHandler = httpClient.getHttpRequestRetryHandler();//获取重试机制
int retryCount = 0;
boolean retry = true;
while (retry) {
try {
HttpResponse response = httpClient.execute(requestBase, httpContext);//访问网络
if (response != null) {
return new HttpResult(response, httpClient, requestBase);
}
} catch (Exception e) {
IOException ioException = new IOException(e.getMessage());
retry = retryHandler.retryRequest(ioException, ++retryCount, httpContext);//把错误异常交给重试机制,以判断是否需要采取从事
LogUtils.e(e);
}
}
return null;
}

/** http的返回结果的封装,可以直接从中获取返回的字符串或者流 */
public static class HttpResult {
private HttpResponse mResponse;
private InputStream mIn;
private String mStr;
private HttpClient mHttpClient;
private HttpRequestBase mRequestBase;

public HttpResult(HttpResponse response, HttpClient httpClient, HttpRequestBase requestBase) {
mResponse = response;
mHttpClient = httpClient;
mRequestBase = requestBase;
}

public int getCode() {
StatusLine status = mResponse.getStatusLine();
return status.getStatusCode();
}

/** 从结果中获取字符串,一旦获取,会自动关流,并且把字符串保存,方便下次获取 */
public String getString() {
if (!TextUtils.isEmpty(mStr)) {
return mStr;
}
InputStream inputStream = getInputStream();
ByteArrayOutputStream out = null;
if (inputStream != null) {
try {
out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024 * 4];
int len = -1;
while ((len = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
byte[] data = out.toByteArray();
mStr = new String(data, "utf-8");
} catch (Exception e) {
LogUtils.e(e);
} finally {
IOUtils.closeQuietly(out);
close();
}
}
return mStr;
}

/** 获取流,需要使用完毕后调用close方法关闭网络连接 */
public InputStream getInputStream() {
if (mIn == null && getCode() < 300) {
HttpEntity entity = mResponse.getEntity();
try {
mIn = entity.getContent();
} catch (Exception e) {
LogUtils.e(e);
}
}
return mIn;
}

/** 关闭网络连接 */
public void close() {
if (mRequestBase != null) {
mRequestBase.abort();
}
IOUtils.closeQuietly(mIn);
if (mHttpClient != null) {
mHttpClient.getConnectionManager().closeExpiredConnections();
}
}
}
}