Android移动架构汇总
AndroidStudio中:导入fastjson、httpclient
##一、 需求:
支持请求 JSON文本类型,音频,图片类型,批量下载。上传
请求各种 数据时,调用层不关心上传参数封装,如(request.addParamas(key,value))
直接将参数封装成对象,传给框架
获取数据后 调用层不关心JSON数据解析
回调时调用层只需要知道传入的JSON的对应的响应类。
回调响应结果发生在主线程(线程切换)
对下载,上传扩展
支持高并发请求,请求队列依次获取,可以设置最大并发数,设置先请求先执行
##二、会用到的知识点
泛型
请求队列
阻塞队列
线程池拒绝策略
设计模式:
模板方法模式
单例模式
策略模式
生产者消费者模式
##三、代码
###1、定义最低层的接口:
业务接口IDataListener:和业务层交互,将返回数据转换成业务需要的类型:
网络回调接口IHttpListener:网络请求回调,获取网络返回数据,再去调用业务接口
网络请求接口:IHttpService:封装请求网络的行为,需要持有请求数据、返回回调的引用
pubic interface IDataListener<M>{
/**
* 回调结果给调用层
* @param m
*/
void onSuccess(M m);
void onFail();
}
public interface IHttpListener {
/**
* 网络访问
* 处理结果 回调
* @param httpEntity
*/
void onSuccess(HttpEntity httpEntity);
void onFail();
}
/**
*获取网络
*/
public interface IHttpService {
/**
* 设置url
* @param url
*/
void setUrl(String url);
/**
* 执行获取网络
*/
void excute();
/**
* 设置处理接口
* @param httpListener
*/
void setHttpListener(IHttpListener httpListener);
/**
* 设置请求参数
* String 1
* byte[] 2
*
*/
void setRequestData(byte[] requestData);
}
###2、封装、调用、管理网络请求
####1)、定义一个实现类封装网络请求需要的请求、执行、回调的所有信息
public class RequestHodler<T> {
/**
* 执行下载类
*/
private IHttpService httpService;
/**
* 获取数据 回调结果的类
*/
private IHttpListener httpListener;
/**
* 请求参数对应的实体
*/
private T requestInfo;
private String url;
public IHttpService getHttpService() {
return httpService;
}
public void setHttpService(IHttpService httpService) {
this.httpService = httpService;
}
public IHttpListener getHttpListener() {
return httpListener;
}
public void setHttpListener(IHttpListener httpListener) {
this.httpListener = httpListener;
}
public T getRequestInfo() {
return requestInfo;
}
public void setRequestInfo(T requestInfo) {
this.requestInfo = requestInfo;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
####2)IHttpService 执行网络请求接口中的请求操作因为耗时需要异步,所以定义一个实现Runnable接口的类来调用。
public class HttpTask<T> implements Runnable {
private IHttpService httpService;
public HttpTask(RequestHodler<T> requestHodler)
{
httpService=requestHodler.getHttpService();
httpService.setHttpListener(requestHodler.getHttpListener());
httpService.setUrl(requestHodler.getUrl());
T request=requestHodler.getRequestInfo();
String requestInfo= JSON.toJSONString(request);
try {
httpService.setRequestData(requestInfo.getBytes("UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
httpService.excute();
}
}
####3)定义一个线程池,用于管理不断被放入的网络请求
public class ThreadPoolManager {
private static final String TAG ="ThreadPoolManager" ;
private static ThreadPoolManager instance=new ThreadPoolManager();
private LinkedBlockingQueue<Future<?>> taskQuene=new LinkedBlockingQueue<>();
private ThreadPoolExecutor threadPoolExecutor;
public static ThreadPoolManager getInstance() {
return instance;
}
private ThreadPoolManager()
{
threadPoolExecutor=new ThreadPoolExecutor(4,10,10,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(4), handler);
threadPoolExecutor.execute(runable);
}
private Runnable runable =new Runnable() {
@Override
public void run() {
while (true) {
FutureTask futrueTask=null;
try {
/**
* 阻塞式函数
*/
Log.i(TAG,"等待队列 "+taskQuene.size());
futrueTask= (FutureTask) taskQuene.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(futrueTask!=null)
{
threadPoolExecutor.execute(futrueTask);
}
Log.i(TAG,"线程池大小 "+threadPoolExecutor.getPoolSize());
}
}
};
public <T> void execte(FutureTask<T> futureTask) throws InterruptedException {
taskQuene.put(futureTask);
}
private RejectedExecutionHandler handler=new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
taskQuene.put(new FutureTask<Object>(r,null) {
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
###3、实现具体请求和回调(以json类型为例)
####1) 实现回调
/**
* M 对应响应类
*/
public class JsonDealLitener<M> implements IHttpListener {
private Class<M> responese;
/**
* 回调调用层 的接口
*/
private IDataListener<M> dataListener;
Handler handler=new Handler(Looper.getMainLooper());
public JsonDealLitener(Class<M> responese, IDataListener<M> dataListener) {
this.responese = responese;
this.dataListener = dataListener;
}
@Override
public void onSuccess(HttpEntity httpEntity) {
InputStream inputStream=null;
try {
inputStream=httpEntity.getContent();
/*
得到网络返回的数据
子线程
*/
String content=getContent(inputStream);
final M m= JSON.parseObject(content,responese);
handler.post(new Runnable() {
@Override
public void run() {
dataListener.onSuccess(m);
}
});
} catch (IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
dataListener.onFail();
}
});
}
}
@Override
public void onFail() {
handler.post(new Runnable() {
@Override
public void run() {
dataListener.onFail();
}
});
}
private String getContent(InputStream inputStream) {
String content=null;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
dataListener.onFail();
}
});
System.out.println("Error=" + e.toString());
} finally {
try {
inputStream.close();
} catch (IOException e) {
System.out.println("Error=" + e.toString());
}
}
return sb.toString();
} catch (Exception e) {
handler.post(new Runnable() {
@Override
public void run() {
dataListener.onFail();
}
});
System.out.println("Error=" + e.toString());
}
return content;
}
}
####2) 实现请求
public class JsonHttpService implements IHttpService {
private IHttpListener httpListener;
private HttpClient httpClient=new DefaultHttpClient();
private HttpPost httpPost;
private String url;
private byte[] requestDate;
/**
* httpClient获取网络的回调
*/
private HttpRespnceHandler httpRespnceHandler=new HttpRespnceHandler();
@Override
public void setUrl(String url) {
this.url=url;
}
@Override
public void excute() {
httpPost=new HttpPost(url);
ByteArrayEntity byteArrayEntity=new ByteArrayEntity(requestDate);
httpPost.setEntity(byteArrayEntity);
try {
httpClient.execute(httpPost,httpRespnceHandler);
} catch (IOException e) {
httpListener.onFail();
}
}
@Override
public void setHttpListener(IHttpListener httpListener) {
this.httpListener=httpListener;
}
@Override
public void setRequestData(byte[] requestData) {
this.requestDate=requestData;
}
private class HttpRespnceHandler extends BasicResponseHandler
{
@Override
public String handleResponse(HttpResponse response) throws ClientProtocolException {
//响应吗
int code=response.getStatusLine().getStatusCode();
if(code==200)
{
httpListener.onSuccess(response.getEntity());
}else
{
httpListener.onFail();
}
return null;
}
}
}
###4、定义工具类封装整个请求过程
public class Volley {
/**
*
* @param <T> 请求参数类型
* @param <M> 响应参数类型
* 暴露给调用层
*/
public static <T,M> void sendRequest(T requestInfo, String url,
Class<M> response, IDataListener dataListener)
{
RequestHodler<T> requestHodler=new RequestHodler<>();
requestHodler.setUrl(url);
IHttpService httpService=new JsonHttpService();
IHttpListener httpListener=new JsonDealLitener<>(response,dataListener);
requestHodler.setHttpService(httpService);
requestHodler.setHttpListener(httpListener);
HttpTask<T> httpTask=new HttpTask<>(requestHodler);
try {
ThreadPoolManager.getInstance().execte(new FutureTask<Object>(httpTask,null));
} catch (InterruptedException e) {
dataListener.onFail();
}
}
}
###5、调用层使用
####1) 请求参数类型
public class User {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
####2) 返回参数类型
public class LoginRespense {
private int code;
private String time;
private String user_id;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
}
####3) 发送请求
String url="http://192.168.100.24:8080/UserRecord/LoginServlet";
User user=new User();
user.setName("13343491234");
user.setPassword("123456");
Volley.sendRequest(user, url, LoginRespense.class, new IDataListener<LoginRespense>() {
@Override
public void onSuccess(LoginRespense loginRespense) {
Log.i(TAG,loginRespense.toString());
}
@Override
public void onFail() {
Log.i(TAG,"获取失败");
}
});
时序图: