给Android封装的一个简单网络请求框架
16lz
2021-01-25
最近做毕业设计,没有用volley框架或则自己以前做项目比较熟悉的beeframework框架的网络请求部分(不得赞一句beeframework的网络请求部分封装得很好,可以研究一下然后自己仿照着写写),本着熟悉和总结andorid一些基础知识的目的,自己试着写了一个自己在毕业设计中用到的网络框架,不喜勿碰。
1.首先是网络请求部分,网络请求没有用android自带的HttpClient,是用的Apache的UrlConnection进行的网络连接。这个网络请求工具返回String类型的结果。拿回然后json解析。
/** * Created by shen-pc on 16/4/9. * * @author shen-pc */public class AccessNetUtil { private static String TAG = "shen"; /** * 得到网络返回的jsonobject * * @param urlString * @return 如果网络返回错误则返回null * @throws IOException * @throws JSONException */ public static String getUrlRes(String urlString, Map params) throws IOException, JSONException { URL url = null; if (null != params && params.size() != 0) { Set set = params.keySet(); urlString += "?"; for (String setStr : set) { urlString = urlString + setStr + "=" + params.get(setStr) + "&"; } urlString = urlString.substring(0, urlString.length() - 1); if (BuildConfig.DEBUG) Log.d(TAG, urlString); } try { url = new URL(urlString); } catch (MalformedURLException e) { Log.e(TAG, "网络错误:MalformedURLException"); return null; } URLConnection connection = null; try { connection = url.openConnection(); } catch (IOException e) { if (BuildConfig.DEBUG) Log.d(TAG, "网络错误:IOException"); return null; } InputStream is = null; InputStreamReader reader; try { is = connection.getInputStream(); } catch (IOException e) { if (BuildConfig.DEBUG) Log.d(TAG, "网络错误:IOException"); return null; } byte[] bs = new byte[1024]; int len; StringBuffer sb = new StringBuffer(); while ((len = is.read(bs)) != -1) { String str = new String(bs, 0, len); sb.append(str); } return sb.toString(); }}
2,然后就是为每一个请求结果建立一个实体,建一个文件夹model文件夹,下面放各种实体类,下面贴一个例子,这是项目中经常会用到的普通的登录model
/** * Created by shen-pc on 16/4/9. */public class LoginModel { private String result; private String code; private String token; private String msg; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String getResult() { return result; } public void setResult(String result) { this.result = result; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } @Override public String toString(){ return "result: " + result +" code: " +code +" token: " +token; }}
3,然后就是json解析了,在项目中新建一个responce文件夹,你面放各种json字段解析类,还是接着登录来说,这里要根据后台返回的json数据结构解析,注意我这里用的opt开头的optJsonObject解析的,因为这个方法做了异常抛出。下面贴下代码:
package com.swu.shen_pc.rolecontrol.response;import com.swu.shen_pc.rolecontrol.model.LoginModel;import com.swu.shen_pc.rolecontrol.model.Products;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.util.ArrayList;import java.util.List;/** * Created by shen-pc on 16/4/9. */public class Login { /** * 解析失败则返回一个空 * @param jsonStr * @return * @throws JSONException */ public static LoginModel parse(String jsonStr) throws JSONException { LoginModel loginModel = null; JSONObject jsonObject = null; if (null != jsonStr && !"".equals(jsonStr)) { loginModel = new LoginModel(); jsonObject = new JSONObject(jsonStr); loginModel.setCode(jsonObject.getString("code")); loginModel.setMsg(jsonObject.optString("msg")); loginModel.setResult(jsonObject.getString("result")); JSONObject valueJsonObj = jsonObject.optJSONObject("value"); try { loginModel.setToken(valueJsonObj.optString("token")); } catch (NullPointerException e) { e.printStackTrace(); } } return loginModel; }}
4,至此我们想要的数据都储存在了loginmodel里面了,然后就是请求的地址,建议写在一个类里面,我是这样处理的:
package com.swu.shen_pc.rolecontrol.response;/** * Created by shen-pc on 16/5/3. */public class AccessUrl { public static final String loginUrl = "http://172.21.216.227:8080/AuthorityMS/login.do"; public static final String getMenuUrl = "http://172.21.216.227:8080/AuthorityMS/menu/queryAll.do"; public static final String getRoleUrl = "http://172.21.216.227:8080/AuthorityMS/role/queryAll.do"; public static final String getUserRoleUrl = "http://172.21.216.227:8080/AuthorityMS/user/queryAll.do"; public static final String addRoleRefUrl = "http://172.21.216.227:8080/AuthorityMS/role/addRoleRef.do"; public static final String addUserRefUrl = "http://172.21.216.227:8080/AuthorityMS/user/addUserAuth.do"; public static final String delRoleRefUrl = "http://172.21.216.227:8080/AuthorityMS/role/deleteRoleRef.do"; public static final String delUserRefUrl = "http://172.21.216.227:8080/AuthorityMS/user/deleteUserAuth.do";}
5,前面基本都是准备工作,然后就是把这些组装起来进行网络请求并解析,我建了i一个类名为Api,这里面全是可以直接调用的网络请求方法:
/** * Created by shen-pc on 16/4/9. */public class Api { private static String TAG = "shen"; public static LoginModel loginModel; private SuccessOrFail successOrFail; public ReponseStatusModel reponseStatusModel; public void addSuccessOrFailCallBack(SuccessOrFail successOrFail) { this.successOrFail = successOrFail; } /** * 登陆 * * @param eMail 邮箱 * @param pwd 密码 */ public void login(String eMail, String pwd) { final Map params = new HashMap<>(); params.put("name", eMail); params.put("password", pwd); new Thread(new Runnable() { @Override public void run() { try { String tempStr = AccessNetUtil.getUrlRes(AccessUrl.loginUrl, params); if (BuildConfig.DEBUG) Log.d(TAG, "tempStr+ " + tempStr); if (null != tempStr) { loginModel = Login.parse(tempStr); if (BuildConfig.DEBUG) Log.d(TAG, loginModel.toString()); } if (null != successOrFail) { if (null != loginModel && "1".equals(loginModel.getCode())) { successOrFail.isSuccess(true,AccessUrl.loginUrl); } else { successOrFail.isSuccess(false,AccessUrl.loginUrl); } } } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } } }).start(); }}
6,全面都是基础的东西,本人认为具有创造性的地方是我在Api里面设置了一个监听器,监听网络是否正确返回,即上面36行到42处的代码:loginModel.getCode是后台返回的结果码(大致是否正确返回的参数),下面是自己写的监听借口: /** * 回调接口,主要是返回一个成功或者访问失败的boolean值 */ public interface SuccessOrFail { /** * @param isSuccess true 表示正确返回结果,否则就失败 * @return */ void isSuccess(boolean isSuccess,String reqUrl); }
然后就是在Activity里里面调用网络请求方法,首先得实现这个接口: public class LoginActivity extends AppCompatActivity implements LoaderCallbacks, Api.SuccessOrFail { private Api loginApi = new Api(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); loginApi.addSuccessOrFailCallBack(this); loginApi.login(email,password); } @Override public void isSuccess(boolean isSuccess, String url) { if (isSuccess) { if (AccessUrl.loginUrl.equals(url)) { //注意这里不能做些更新界面的操作,如果可以做更新界面的操作可以用自己写个handler操作,当然这里可以在isSucess中传递context,然后直接刷新 } } else { } } }
到这里基本就是我封装的网络框架思路,不足之处请留言指点。
更多相关文章
- Nginx系列教程(六)| 手把手教你搭建 LNMP 架构并部署天空网络电影
- 实现Android的不同精度的定位(基于网络和GPS)[转]
- gradle常用命令和查看错误
- Android(安卓)导入android源码有错,R.java文件不能自动生成解决方
- Android(安卓)studio中配置androidannotations框架
- Android(安卓)获取并显示远程图片 Picasso框架的使用
- 开发手机刷机工具箱的过程
- Android(安卓)adb网络连接Offline和 adb断开连接
- android中常见的网络框架