//首先是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(); } 这是最近自己结合两者设置的一个框架,后续有时间可能还会慢慢解耦,有意见请大家提出来~~~~
