最近看到了一篇关于阿里何洪辉的singlenet框架,然后自己结合了mvp框架自己架构了一个简单的程序框架,接下去我将以登录模块来说明一下我的这个小框架
首先是singlenet的框架,这个框架的知识是照搬书上的
//然后一个jsonRequest的实现,覆盖父类的数据解析方法,返回jsonobject
//response和request完成后,书写一个请求队列进行处理请求
//请求队列中的执行器,获得请求队列开启线程进行处理
//接下去是网络请求的真正执行者,通过request获取response
//response传递者,将response传递到UI线程中
//model请求网络完成后的回调,网络中介完成请求后,通过responseReveive传递给model
首先是singlenet的框架,这个框架的知识是照搬书上的
//首先是request的抽象类,根据http协议的格式设置response内容
package net;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Administrator on 2017/4/5.
*/
public abstract class Request<T> implements Comparable<Request<T>> {
public static enum HttpMethod{
GET,
POST,
PUT,
DELETE
}
public static enum Priority{
LOW,
NORMAL,
HIGHT,
IMMEDIATE
}
//设置默认编码
private static String DEFAULT_PARAMS_ENCODING ="UTF-8";
//请求序列号
protected int mSerialNum = 0;
//请求优先级
protected Priority priority =Priority.NORMAL;
//是否取消请求
protected boolean isCancle = false;
//是否需要缓存
private boolean mShouldCache =true;
//请求回调
public RequestListener<T> mRequestListener;
//请求url
private String mUrl ="";
//请求方法
HttpMethod mMethod =HttpMethod.GET;
//请求的head
private Map<String,String> mHeads = new HashMap<String,String>();
//请求参数
private Map<String,String> mBodyParams = new HashMap<String,String>();
public Request(HttpMethod mMethod,String mUrl,RequestListener<T> mRequestListener){
this.mMethod = mMethod;
this.mUrl = mUrl;
this.mRequestListener = mRequestListener;
}
public abstract T parseResponse(Response response);
public final void deliveryResponse(Response response){
T result = parseResponse(response);
//设置监听
if( mRequestListener!=null){
int stCode =response!=null?200:-1;
String msg = response!=null?"ok":"unknow error";
mRequestListener.onComplete(stCode,result,msg);
}
}
protected String getParamsEncoding(){
return DEFAULT_PARAMS_ENCODING;
}
public String getBodyContendType(){
return "application/x-www-form-urlencoded;charset="+getParamsEncoding();
}
public Map getParams(){
return mBodyParams;
}
public static String getDefaultParamsEncoding() {
return DEFAULT_PARAMS_ENCODING;
}
public static void setDefaultParamsEncoding(String defaultParamsEncoding) {
DEFAULT_PARAMS_ENCODING = defaultParamsEncoding;
}
public int getmSerialNum() {
return mSerialNum;
}
public void setmSerialNum(int mSerialNum) {
this.mSerialNum = mSerialNum;
}
public Priority getPriority() {
return priority;
}
public void setPriority(Priority priority) {
this.priority = priority;
}
public boolean isCancle() {
return isCancle;
}
public void setCancle(boolean cancle) {
isCancle = cancle;
}
public boolean ismShouldCache() {
return mShouldCache;
}
public void setmShouldCache(boolean mShouldCache) {
this.mShouldCache = mShouldCache;
}
public HttpMethod getmMethod() {
return mMethod;
}
public void setmMethod(HttpMethod mMethod) {
this.mMethod = mMethod;
}
public String getmUrl() {
return mUrl;
}
public void setmUrl(String mUrl) {
this.mUrl = mUrl;
}
public Map<String, String> getmHeads() {
return mHeads;
}
public void setmHeads(Map<String, String> mHeads) {
this.mHeads = mHeads;
}
public Map<String, String> getmBodyParams() {
return mBodyParams;
}
public void setmBodyParams(Map<String, String> mBodyParams) {
this.mBodyParams = mBodyParams;
}
public byte[] getBody(){
Map<String,String> params = getParams();
if(params!=null&¶ms.size()>0){
return encodedParams(params,getParamsEncoding());
}
return null;
}
//body格式
private byte[] encodedParams(Map<String,String> params,String paramsEncoding){
StringBuilder encodedParamters = new StringBuilder();
int size =params.entrySet().size();
int index =1;
try {
for(Map.Entry<String,String> entry:params.entrySet()){
encodedParamters.append(URLEncoder.encode(entry.getKey(),paramsEncoding));
encodedParamters.append("=");
encodedParamters.append(URLEncoder.encode(entry.getValue(),paramsEncoding));
if(index!=size){
encodedParamters.append("&");
}
index++;
}
return encodedParamters.toString().getBytes(paramsEncoding);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new byte[0];
}
@Override
public int compareTo(Request<T> another) {
Priority myPriority = getPriority();
Priority anotherPriority = another.getPriority();
return myPriority.equals(anotherPriority)?this.getmSerialNum()-another.getmSerialNum():myPriority.ordinal()-anotherPriority.ordinal();
}
//回调接口
public static interface RequestListener<T>{
public void onComplete(int stCode,T response,String errMsg);
}
}
//然后一个jsonRequest的实现,覆盖父类的数据解析方法,返回jsonobject
package net;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created by Administrator on 2017/4/30.
*/
public class JsonRequest extends Request<JSONObject>{
public JsonRequest(HttpMethod mMethod, String mUrl, RequestListener<JSONObject> mRequestListener) {
super(mMethod, mUrl, mRequestListener);
}
@Override
public JSONObject parseResponse(Response response) {
if(response!=null){
String jsonString = new String(response.getRowData());
try {
return new JSONObject(jsonString);
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
}
//response类,接收网络请求的响应内容
package net;
import org.apache.http.HttpEntity;
import org.apache.http.ProtocolVersion;
import org.apache.http.StatusLine;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
/**
* Created by Administrator on 2017/4/5.
*/
public class Response extends BasicHttpResponse {
byte[] rowData = new byte[0];
private int statusCode;
public int getStatusCode() {
return statusCode;
}
@Override
public void setStatusCode(int statusCode) {
this.statusCode = statusCode;
}
public Response(StatusLine statusline) {
super(statusline);
}
public Response(ProtocolVersion ver, int code, String reason) {
super(ver, code, reason);
}
@Override
public void setEntity(HttpEntity entity) {
super.setEntity(entity);
rowData = entityToBytes(entity);
}
public byte[] getRowData(){
return rowData;
}
private byte[] entityToBytes(HttpEntity entity){
try {
return EntityUtils.toByteArray(entity);
} catch (IOException e) {
e.printStackTrace();
}
return new byte[0];
}
}
//response和request完成后,书写一个请求队列进行处理请求
package net;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Created by Administrator on 2017/4/5.
*/
public class RequestQueue{
private BlockingQueue<Request<?>> mRequestQueue= new PriorityBlockingQueue<Request<?>>();
private AtomicInteger atomicInteger = new AtomicInteger(0);
public static int DEFAULT_CORE_NUMS = Runtime.getRuntime().availableProcessors()+1;
private int mDispatcherNums =DEFAULT_CORE_NUMS;
private NetWorkExecutor[] mDispatchers = null;
private HttpStack httpStack;
public RequestQueue(){
this(DEFAULT_CORE_NUMS,null);
}
protected RequestQueue(int coreNums,HttpStack httpStack){
this.mDispatcherNums = coreNums;
this.httpStack = httpStack!=null?httpStack:HttpStackFactory.createHttpStack();
}
private final void startNetworkExecutors(){
mDispatchers = new NetWorkExecutor[mDispatcherNums];
for(int i=0;i<mDispatcherNums;i++){
mDispatchers[i] = new NetWorkExecutor(mRequestQueue,httpStack);
mDispatchers[i].start();
}
}
public void start(){
stop();
startNetworkExecutors();
}
public void stop(){
if(mDispatchers!=null&&mDispatchers.length>0){
for(int i=0;i<mDispatchers.length;i++){
mDispatchers[i].quit();
}
}
}
public void addRequest(Request<?> request){
if(!mRequestQueue.contains(request)){
request.setmSerialNum(generateSerialNumber());
mRequestQueue.add(request);
}
}
private int generateSerialNumber(){
return atomicInteger.incrementAndGet();
}
}
//请求队列中的执行器,获得请求队列开启线程进行处理
package net;
import android.util.Log;
import android.util.LruCache;
import java.util.concurrent.BlockingQueue;
/**
* Created by Administrator on 2017/4/9.
*/
public class NetWorkExecutor extends Thread {
private BlockingQueue<Request<?>> mRequestQueue;
private HttpStack mHttpStack;
private static ResponseDelivery mResponseDelivery = new ResponseDelivery();
private static LruCache<String,Response> mreqCache = new LruCache<String,Response>(100);
private boolean isStop = false;
public NetWorkExecutor(BlockingQueue<Request<?>> mRequestQueue,HttpStack httpStack){
this.mRequestQueue=mRequestQueue;
this.mHttpStack = httpStack;
}
@Override
public void run() {
while(!isStop){
try {
final Request<?> request = mRequestQueue.take();
if(request.isCancle()){
Log.d("###","###取消执行");
continue;
}
Response response=null;
if(isUserCache(request)){
response=mreqCache.get(request.getmUrl());
}else{
response = mHttpStack.performRequest(request);
if(response==null){
System.out.println("返回response为空");
}
if(request.ismShouldCache()&&isSuccess(response)){
mreqCache.put(request.getmUrl(),response);
}
}
mResponseDelivery.deliveryResponse(request,response);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private boolean isSuccess(Response response){
return response!=null&&response.getStatusCode()==200;
}
private boolean isUserCache(Request<?> request){
return request.ismShouldCache()&& mreqCache.get(request.getmUrl())!=null;
}
public void quit(){
isStop=true;
interrupt();
}
}
//接下去是网络请求的真正执行者,通过request获取response
package net;
import com.baidu.trace.T;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.ProtocolVersion;
import org.apache.http.StatusLine;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicStatusLine;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Created by Administrator on 2017/4/9.
*/
public class HttpUrlConnecStack implements HttpStack {
@Override
public Response performRequest(Request<?> request) {
HttpURLConnection urlConnection =null;
try {
urlConnection =createUrlConnection(request.getmUrl());
System.out.println("设置头部");
setRequestHeaders(urlConnection,request);
System.out.println("设置参数");
setRequestParams(urlConnection,request);
urlConnection.connect();
return fetchResponse(urlConnection);
} catch (IOException e) {
e.printStackTrace();
System.out.println("异常是"+e.toString());
}finally {
if(urlConnection!=null){
urlConnection.disconnect();
}
}
return null;
}
private HttpURLConnection createUrlConnection(String url) throws IOException {
URL newURL = new URL(url);
URLConnection urlConnection = newURL.openConnection();
urlConnection.setDoInput(true);
urlConnection.setUseCaches(false);
return (HttpURLConnection) urlConnection;
}
private void setRequestHeaders(HttpURLConnection connection,Request<?> request){
Set<String> headersKeys = request.getmHeads().keySet();
for(String headerName:headersKeys){
connection.addRequestProperty(headerName,request.getmHeads().get(headerName));
}
}
protected void setRequestParams(HttpURLConnection connection,Request<?> request) throws IOException {
Request.HttpMethod method=request.getmMethod();
connection.setRequestMethod(method.toString());
//connection.setRequestMethod("POST");
byte[] body =request.getBody();
String params = new String(body);
System.out.println("参数是"+params);
if(body!=null){
connection.setDoInput(true);
connection.addRequestProperty("Content-Type",request.getBodyContendType());
DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
dataOutputStream.write(body);
dataOutputStream.close();
}
}
private Response fetchResponse(HttpURLConnection connection) throws IOException {
ProtocolVersion protocolVersion = new ProtocolVersion("HTTP",1,1);
int responseCode = connection.getResponseCode();
if(responseCode==-1){
System.out.println("抛出异常!");
throw new IOException("Could not retrieve response code from HttpUrlConnection");
}
System.out.println("请求链接成功!");
StatusLine responseStatus = new BasicStatusLine(protocolVersion,connection.getResponseCode(),connection.getResponseMessage());
Response response = new Response(responseStatus);
response.setStatusCode(connection.getResponseCode());
response.setEntity(entityFromURLConnection(connection));
addHeadersToResponse(response,connection);
return response;
}
private HttpEntity entityFromURLConnection(HttpURLConnection connection){
BasicHttpEntity entity = new BasicHttpEntity();
InputStream inputStream =null;
try {
inputStream = connection.getInputStream();
} catch (IOException e) {
e.printStackTrace();
inputStream= connection.getErrorStream();
}
entity.setContent(inputStream);
entity.setContentLength(connection.getContentLength());
entity.setContentType(connection.getContentType());
return entity;
}
private void addHeadersToResponse(BasicHttpResponse response,HttpURLConnection connection){
for(Map.Entry<String,List<String>> header:connection.getHeaderFields().entrySet()){
if(header.getKey()!=null){
Header h = new BasicHeader(header.getKey(),header.getValue().get(0));
response.setHeader(h);
}
}
}
}
//response传递者,将response传递到UI线程中
package net;
import android.os.Handler;
import android.os.Looper;
import java.util.concurrent.Executor;
/**
* Created by Administrator on 2017/4/9.
*/
public class ResponseDelivery implements Executor {
Handler mResponseHandler = new Handler(Looper.getMainLooper());
public void deliveryResponse(final Request<?>request,final Response response){
Runnable responseRunnable = new Runnable() {
@Override
public void run() {
request.deliveryResponse(response);
}
};
execute(responseRunnable);
}
@Override
public void execute(Runnable runnable) {
mResponseHandler.post(runnable);
}
}
以上整个网络框架就完成了,接下去就是结合mvp框架
//首先是view的接口
package viewinterface;
/**
* Created by Administrator on 2017/4/30.
*/
public interface LoginViewInterface {
void loginSuccess();
void loginFailed(String errorMessage);
void registFailed(String errorMessage);
void regustSuccess();
void doLogin();
void doRegist();
}
//view的实现LoginView,充当view视图,只进行视图的转换
package com.example.administrator.exercise;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import FileUtils.ImageLoader;
import Manager.MyDialogFactory;
import chart.imp.ImgeSelectorActivity;
import present.LoginPresent;
import viewinterface.LoginViewInterface;
/**
* Created by Administrator on 2017/4/30.
*/
public class LoginActivtity extends Activity implements LoginViewInterface,View.OnClickListener{
private TextView phoneText ;
private TextView passwordText;
private Button loginButton;
private Button registButton;
private ImageView logoImage;
private LoginPresent present;
private ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
init();
}
@Override
protected void onResume() {
super.onResume();
}
private void init(){
phoneText = (TextView) findViewById(R.id.phone_text);
passwordText = (TextView) findViewById(R.id.password_text);
loginButton = (Button) findViewById(R.id.login_button);
registButton = (Button) findViewById(R.id.regist_button);
logoImage = (ImageView) findViewById(R.id.logo_image);
present = new LoginPresent(this);
dialog = MyDialogFactory.getInstance().createProgressDialog("请稍后。。。",this);
setListener();
}
private void setListener(){
loginButton.setOnClickListener(this);
registButton.setOnClickListener(this);
logoImage.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.login_button:
present.login(phoneText.getText().toString().trim(),
passwordText.getText().toString());
break;
case R.id.regist_button:
present.regist(phoneText.getText().toString().trim(),
passwordText.getText().toString().trim());
break;
}
}
@Override
public void loginSuccess() {
Toast.makeText(this,"成功",Toast.LENGTH_LONG).show();
Intent intent = new Intent();
intent.setClass( LoginActivtity.this,MainActivity.class);
startActivity(intent);
dialog.dismiss();
}
@Override
public void loginFailed(String errorMessage) {
Toast.makeText(this,"登录失败:"+errorMessage,Toast.LENGTH_LONG).show();
dialog.dismiss();
}
@Override
public void registFailed(String errorMessage) {
Toast.makeText(this,"注册失败"+errorMessage,Toast.LENGTH_LONG).show();
dialog.dismiss();
}
@Override
public void regustSuccess() {
Toast.makeText(this,"注册成功",Toast.LENGTH_LONG).show();
dialog.dismiss();
}
@Override
public void doLogin() {
dialog.show();
}
@Override
public void doRegist() {
dialog.show();
}
}
//present中介,实现onLoginListener接口,接收model中不同的情况进行不同的处理,同时拥有view 和model的对象,对view和model进行解耦数据获取数据后直接在里面进行设置视图
package present;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
import Listener.OnLoginListener;
import model.LoginModel;
import model.LoginModelInterface;
import proxy.MiddleNetProxy;
import proxy.ResponsReceiver;
import viewinterface.LoginViewInterface;
/**
* Created by Administrator on 2017/4/30.
*/
public class LoginPresent implements OnLoginListener {
LoginViewInterface loginViewInterface;
LoginModelInterface loginModelInterface;
public LoginPresent( LoginViewInterface loginViewInterface){
this.loginViewInterface = loginViewInterface;
loginModelInterface = new LoginModel();
loginModelInterface.setOnLoginListener(this);
}
public void login(String phone,String password){
loginModelInterface.doLogin(phone,password);
}
public void regist(String phone,String password){
if(!"".equals(phone)&&!"".equals(password)){
loginViewInterface.doRegist();
loginModelInterface.doRegist(phone,password);
}
}
@Override
public void loginSuccess() {
loginViewInterface.loginSuccess();
}
@Override
public void loginFailed(String errorMessage) {
loginViewInterface.loginFailed(errorMessage);
}
@Override
public void registFailed(String errorMessage) {
loginViewInterface.registFailed(errorMessage);
}
@Override
public void regustSuccess() {
loginViewInterface.regustSuccess();
}
}
//然后是model数据获取,集成responseReveive,在hanler中处理网络中介返回来的response,并且通过onLoginListener传递给present,
package model;
import android.content.Context;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import FileUtils.TempURL;
import Listener.OnLoginListener;
import proxy.MiddleNetProxy;
import proxy.ResponsReceiver;
/**
* Created by Administrator on 2017/5/4.
*/
public class LoginModel implements LoginModelInterface , ResponsReceiver<JSONObject>{
private static String KEY_ACCOUNT = "userPhone";
private static String KEY_PASSWORD = "userPassword";
private static String TYPE_LOGIN = "LOGIN";
private static String TYPE_REGIST = "REGIST";
private Context context;
public LoginModel(){
}
public LoginModel(Context context){
this.context = context;
}
@Override
public void setOnLoginListener(OnLoginListener onLoginListener) {
this.onLoginListener = onLoginListener;
}
private OnLoginListener onLoginListener;
@Override
public int doLogin(String account, String passWord) {
HashMap<String,String> loginMap = new HashMap<String,String>();
loginMap.put(KEY_ACCOUNT,account);
loginMap.put(KEY_PASSWORD, passWord);
MiddleNetProxy.getInstance().postJsonRequest(TempURL.host+"/User/login",this,loginMap,null,false);
return 0;
}
@Override
public int doRegist(String account, String passWord) {
HashMap<String,String> registMap = new HashMap<String,String>();
System.out.println("账号是"+account);
registMap.put(KEY_ACCOUNT,account);
registMap.put(KEY_PASSWORD,passWord);
MiddleNetProxy.getInstance().postJsonRequest(TempURL.host+"/User/addUser",this,registMap,null,false);
return 0;
}
@Override
public void handlerResponse(int stCode, JSONObject response, String errMsg) {
if(response==null)return;
System.out.println("result="+response.toString());
//根据返回的协议进行分发
try {
String type = response.getString(TYPE);
if(TYPE_LOGIN.equalsIgnoreCase(type)){
String msg = response.getString(MSG);
String info = response.getString(INFO);
if(MSG_OK.equalsIgnoreCase(msg)){
if(onLoginListener!=null){
onLoginListener.loginSuccess();
}
}else if(MSG_ERROR.equalsIgnoreCase(msg)){
if(onLoginListener!=null){
onLoginListener.loginFailed(info);
}
}
}else if(TYPE_REGIST.equalsIgnoreCase(type)){
String msg = response.getString(MSG);
String info = response.getString(INFO);
if(MSG_OK.equalsIgnoreCase(msg)){
if(onLoginListener!=null){
onLoginListener.regustSuccess();
}
}else if(MSG_ERROR.equalsIgnoreCase(msg)){
if(onLoginListener!=null){
onLoginListener.registFailed(info);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
//网络请求中介,用于传递请求,管理请求队列
package proxy;
import net.JsonRequest;
import net.Request;
import net.RequestQueue;
import net.ResponseDelivery;
import org.json.JSONObject;
import java.util.Map;
/**
* Created by Administrator on 2017/4/30.
*/
public class MiddleNetProxy {
public static MiddleNetProxy instance;
private static RequestQueue mQueue = new RequestQueue();
MiddleNetProxy(){
mQueue.start();
}
public static synchronized MiddleNetProxy getInstance(){
if(instance==null){
instance = new MiddleNetProxy();
}
return instance;
}
public static void postJsonRequest(String url, final ResponsReceiver receiver,Map<String,String> body,Map<String,String> header,boolean isUseCase){
JsonRequest request = new JsonRequest(Request.HttpMethod.POST, url, new Request.RequestListener<JSONObject>() {
@Override
public void onComplete(int stCode, JSONObject response, String errMsg) {
if(receiver!=null){
receiver.handlerResponse(stCode,response,errMsg);
}
}
});
request.setmShouldCache(isUseCase);
if(header!=null)
request.setmHeads(header);
if(body!=null){
request.setmBodyParams(body);
}
mQueue.addRequest(request);
}
}
//model请求网络完成后的回调,网络中介完成请求后,通过responseReveive传递给model
public interface ResponsReceiver<T> {
void handlerResponse(int stCode,T response, String errMsg);
}
//onLoginListener获得present引用,因为present中实现了该接口,所以可以直接在model里面使用onLoginListener来调用present的视图设置的函数
public interface OnLoginListener {
void loginSuccess();
void loginFailed(String errorMessage);
void registFailed(String errorMessage);
void regustSuccess();
}
这是最近自己结合两者设置的一个框架,后续有时间可能还会慢慢解耦,有意见请大家提出来~~~~