网络框架AndNet—解放你的时间
Posted 亓斌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络框架AndNet—解放你的时间相关的知识,希望对你有一定的参考价值。
吐槽
我们做移动开发的,网络操作可以说是最最常用的技术了,而在网络操作中http又是一块最常见的的方式,返回json的http请求可以说是我们日常最长干的活。你一般用什么框架去请求http呢?Volley?OkHttp? 不管哪种方式用起来是不是还是不那么的方便,我们依然要写大量的请求、解析、返回的代码。好,这篇博客,不是让你替换掉你最常用的那个网络框架,而是在你熟悉的框架之上二次封装!目的就是为了解放你的时间,让网络操作更简单、漂亮。
需求
虽然现在我们有诸如Volley、OkHttp等很好的框架使用,但是你是不是还感觉这部分还是那么的麻烦?你是不是想让每次请求到解析出来几行代码就可以搞定?
下面的两种方式你更喜欢哪种?
MultipartBuilder builder = new MultipartBuilder()
.type(MultipartBuilder.FORM);
...
builder.addPart(Headers.of("Content-Disposition",
"form-data; name=\\""+ key +"\\""),
RequestBody.create(null, map.get(key)));
...
Request request = new Request.Builder()
.url(url).post(builder.build()).build();
call(request, parser, callback);
RequestParams params = new RequestParams("name", "loader");
params.add("age", 18).add("city", "jinan");
Net.post("http://192.168.3.116/", params, new CommParser<User>("user")
,
new Net.Callback<User>()
@Override
public void callback(Result<User> result)
if(result.getStatus() == Result.SUCCESS)
User user = result.getResult();
mTextView.setText(user.getName());
...
else
mTextView.setText(result.getMsg());
);
显然第二种方式是我们想要的,有了需求,那我们就得考虑封装了,我在不断尝试以后,终于完成了这种优雅方式的框架的一个小封装,哦,给了它一个特别骚的名字-AndNet,AndNet不仅仅具备上面的便捷功能,它还允许我们随时任意更换我们使用的底层网络请求框架,而不需要改动我们的业务逻辑代码,这一点太棒了!哪天Volley不再适合我们了,我们可以直接切换到OkHttp,而我们的业务代码不需要任何的改变,兴奋ing,下面就让我们开始尝试使用AndNet吧。
准备工作
AndNet默认的网络请求框架是使用的OkHttp,所以你需要在你的项目中添加一下两个依赖:
compile 'com.squareup.okhttp:okhttp:2.0.0'
compile 'com.squareup.okio:okio:1.5.0'
接下来,我们需要自定义一个Application,在它的onCreate中添加一行代码,
Net.init(new OkHttpStack());
现在我们就指定使用默认的网络请求框架OkHttp,当然如果我们想切换框架,也是在这里做。
自定义parser
在我们开始使用之前,还需要做一件事就是根据你们项目使用的json格式,定义需要的json的parser类,parser部分我是很想写到框架里面的,不过那样灵活性就差了,所以这里还是需要我们在自己的项目里写自己的parser。
假如现在我们json的格式如下,
success: true,
message: "",
user: -
age: "18",
name: "loader",
city: "jinan"
这种格式在我们项目中肯定是固定的,所以我们无需担心格式泛滥,json的解析你可以任意写,不过还是推荐使用fastjson来搞,这样太方便了。
来看看根据这种格式写出来的parser什么样吧。
public class CommParser<T> implements Net.Parser<T>
private String mKey;
public CommParser(String key)
mKey = key;
@Override
public Result<T> parse(String response)
Result<T> result = new Result<T>();
try
JSONObject baseObject = JSON.parseObject(response);
if(!baseObject.getBooleanValue("success"))
result.setMsg(baseObject.getString("message"));
else
Class<T> klass = Helper.generateType(getClass());
if(klass == null) throw new Exception();
T t = baseObject.getObject(mKey, klass);
result.setStatus(Result.SUCCESS);
result.setResult(t);
return result;
catch (Exception e)
e.printStackTrace();
result.setMsg(Net.ERR_PARSE_MSG);
result.setStatus(Result.ERROR);
return result;
首先这个Parser要知道我们关心哪个部分内容,所以我们需要在构造里传递一个key,对应上面的json格式就是user啦,接下来我们重写parse方法,使用fastjson将我们需要的数据解析出来了,这里面我们使用了Helper.generateType方法,这个方法是AndNet提供的一个方法,目的就是获取泛型的类型,我们CommParser的是泛型的。在你的项目中,你完全可以copy一下这个parser,然后改成你的逻辑。
ok, 既然parser我们定义好了,那我们接下来就进入AndNet的使用吧。
使用AndNet做get请求
get请求很简单,不需要任何参数,我们直接使用
Net.get(final String url, final Parser<T> parser, final Callback<T> callback);
就可以了
Net.get("http://192.168.3.116/?name=loader&age=18&city=jinan",
new CommParser<User>("user") , new Net.Callback<User>()
@Override
public void callback(Result<User> result)
if(result.getStatus() == Result.SUCCESS)
User user = result.getResult();
mTextView.setText(user.getName());
mTextView.append("\\n" + user.getAge());
mTextView.append("\\n" + user.getCity());
else
mTextView.setText(result.getMsg());
);
调用一个方法,我们就搞定了从请求到解析的操作,是不是很方便!
使用AndNet做post请求
post请求估计是使用Net.post了,它的原型是:
Net.post(final String url, final RequestParams params, final Parser<T> parser, final Callback<T> callback);
仅仅多了一个RequestParams的参数,这个参数就是我们需要post的参数了,下面来看看post怎么使用,
RequestParams params = new RequestParams("name", "loader");
params.add("age", 18).add("city", "jinan");
Net.post("http://192.168.3.116/", params, new CommParser<User>("user")
,
new Net.Callback<User>()
@Override
public void callback(Result<User> result)
if(result.getStatus() == Result.SUCCESS)
User user = result.getResult();
mTextView.setText(user.getName());
mTextView.append("\\n" + user.getAge());
mTextView.append("\\n" + user.getCity());
else
mTextView.setText(result.getMsg());
);
和get一样简单,只不过是RequestParams构造出来的参数。另外AndNet还提供了另外一种post的方式,使用起来也特别爽-直接传递一个java bean!
首先我们定义一个参数的javabean,我们提交的参数有:name、age、city。
public class User implements IBaseBean
@Annotation(key = "name")
private String name;
@Annotation(key = "age")
private int age;
@Annotation(key = "city")
private String city;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getCity()
return city;
public void setCity(String city)
this.city = city;
public int getAge()
return age;
public void setAge(int age)
this.age = age;
@Override
public String toString()
return "name=" + name + ",age=" + age + ",city=" + city;
User实现了IBaseBean接口,这个接口是一个空接口,仅仅代表它是一个可以作为参数的类,User里的字段我们使用了Annotation
注解来标记它所对应的参数的key。
定义完bean后,我们接下来就是提交它的操作了。
User user = new User();
user.setName("qibin");
user.setCity("shandong");
user.setAge(18);
Net.post("http://192.168.3.116/", user, new CommParser<User>("user")
, new Net.Callback<User>()
@Override
public void callback(Result<User> result)
if(result.getStatus() == Result.SUCCESS)
mTextView.setText(result.getResult().toString());
else
mTextView.setText(result.getMsg());
);
和上面普通的post一样,这里我们仅仅是将RequestParams替换成了User的对象。这种方式是不是看起来更加清爽呢!
文件上传
AndNet支持文件上传,不过这里的支持还是得依靠我们的HttpStack的实现,默认提供了OkHttpStack就支持文件上传操作,文件上传操作和我们上面说的post操作没有任何区别,只需要给RequestParams一个File类型的值就ok。
RequestParams params = new RequestParams("name", "qibin");
params.add("file", new File(Environment.getExternalStorageDirectory()
+ "/demo.doc"));
Net.post("http://192.168.3.116/upload.php", params, new Net.NoParser(),
new Net.Callback<String>()
@Override
public void callback(Result<String> result)
mTextView.setText(result.getResult() + "");
);
其他任何特殊的代码都没有,这样我们就完成了上传功能。
AndNet的高级使用-自定义HttpStack
上面提到过,AndNet支持切换使用的网络框架,这就需要我们自定义HttpStack来实现,自定义HttpStack我们需要继承AbsHttpStack
,下面我们就以自定义VolleyStack为例,替换默认的OkHttp,
public class VolleyStack<T> extends AbsHttpStack<T>
private Application mContext;
public VolleyStack(Application context)
mContext = context;
/**
* get请求
*
* @param url 网址
* @param parser 解析器
* @param callback 回调
*/
@Override
public void get(String url, Net.Parser<T> parser,
Net.Callback<T> callback, final Object tag)
invoke(Request.Method.GET, url, null, parser, callback, tag);
/**
* post请求
*
* @param url 访问的url
* @param params post参数
* @param parser 解析器
* @param callback 回调
*/
@Override
public void post(String url, RequestParams params,
Net.Parser<T> parser,
Net.Callback<T> callback,
final Object tag)
invoke(Request.Method.POST, url, params, parser, callback, tag);
/**
* 执行网络请求
*
* @param url
* @param params post时请求的参数 get时为null
* @param parser
* @param callback
* @param method
*/
private void invoke(final int method, final String url,
final RequestParams params,
final Net.Parser<T> parser,
final Net.Callback<T> callback,
final Object tag)
StringRequest request = new StringRequest(method, url,
new Response.Listener<String>()
public void onResponse(String response)
onNetResponse(parser, callback, response);
, new Response.ErrorListener()
public void onErrorResponse(VolleyError error)
error.printStackTrace();
onError(callback, Net.DEF_ERR_MSG);
)
@Override
protected Map<String, String> getParams()
throws AuthFailureError
if (params != null) return params.get();
return super.getParams();
;
VolleyManager.getInstance(mContext).add(request, tag);
@Override
public void cancel(Object tag)
VolleyManager.getInstance(mContext).cancel(tag);
这里重写了AbsHttpStack的get
和post
方法,这里面都调用了我们自定义的invoke
方法,在invoke
中我们使用Volley进行网络请求,在请求成功后调用了onNetResponse(parser, callback, response)
方法,
在请求失败后调用了onError(callback, Net.DEF_ERR_MSG)
方法,这两个方法在AbsHttpStack
已经实现,我们无需关心。
好了,新的HttpStack定义好了,那我们就来切换一下吧。
public class App extends Application
@Override
public void onCreate()
super.onCreate();
Net.init(new VolleyStack(this));
// Net.init(new OkHttpStack());
修改一行代码,就完成了网络框架的切换,而我们的业务代码无需任何变动,是不是很爽?
AndNet的高级使用-添加header
有时候我们的项目需要一些自定义的header,我们完全可以通过扩展OkHttpStack
来完成这个功能。
public class OkHttpHeaderStack<T> extends OkHttpStack<T>
@Override
public LinkedHashMap<String, String> headers()
LinkedHashMap<String, String> headers = new LinkedHashMap<>();
headers.put("name", "header");
return headers;
我们继承了OkHttpStack
类,并重写了headers
方法,将我们需要的header放到一个map里返回,再次替换我们使用的HttpStack
public class App extends Application
@Override
public void onCreate()
super.onCreate();
// Net.init(new VolleyStack(this));
// Net.init(new OkHttpStack());
Net.init(new OkHttpHeaderStack());
完美解决! 好了,这样AndNet的功能我们就学习完了,最后是AndNet的下载地址,包含了源码、jar包和实例代码,欢迎各方star。
https://github.com/qibin0506/AndNet
以上是关于网络框架AndNet—解放你的时间的主要内容,如果未能解决你的问题,请参考以下文章