最近做毕业设计,没有用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<String, String> params) throws IOException, JSONException {
URL url = null;
if (null != params && params.size() != 0) {
Set<String> 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<String, String> 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<Cursor>, 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 {
}
}
}
到这里基本就是我封装的网络框架思路,不足之处请留言指点。