开源网络框架Nohttp有着非常大的优势,首先他是由国人严振杰研发的,有详细的中文文档,方便于我们进行研究和使用。其次,Nohttp的有着最大的优点:可以自由选择底层框架是HttpUrlConnection还是Okhttp,它可以说是volley的升级版。但开发中,我们根据自己的需求,依然要对其进行二次封装,以达到,在使用NOhttp请求网络时,自带自定义的进度条对话框,简化一些冗余代码,使用一个RequestQueue队列,节约内存。
完成后的效果图:
一、关联Nohttp网络框架、初始化、清单文件加入权限、页面布局
我是用HttpUrlConnection作为底层框架,至于权限和布局这些都很基础了,可以参考我的上一篇博客
Nohttp的使用(一): http://blog.csdn.net/bo543937071/article/details/53609360
注意:要在Application中进行初始化,同时在清单文件里进行注册。
二、定义接口:
自定义一个NOhttp请求网络的监听器接口,使用二次封装的NOhttp,必须实现该接口,以便于覆写,两个方法分别是:网络请求成功的抽象方法,网络请求失败的抽象方法。
public interface HttpListener<T> { //请求网络成功回调的监听方法 void onSucceed(int what, Responseresponse); //请求网络成功回调的监听方法 void onFailed(int what, Response response); } 三、自定义进度条对话框类: 进度条对话框就是效果图中点击按钮会弹出"请稍候。。。"的对话框。 代码如下:
public class WaitDialog extends ProgressDialog{ public WaitDialog(Context context) { super(context); //设置当前的Activity无title,并且全屏(调用这个方法必须在setContentView之前调用) requestWindowFeature(Window.FEATURE_NO_TITLE); //设置在对话框的外面点击,是否让对话框消失,false是可以取消 setCanceledOnTouchOutside(false); //设置对话框的样式 setProgressStyle(STYLE_SPINNER); //设置进度条对话框显示的内容 setMessage("正在请求网络,请稍候。。。。"); } public WaitDialog(Context context, int theme) { super(context, theme); } }四、自定义一个类实现NOhttp对于请求网络的监听器,使用这个自定义监听请求网络会带一个进度条对话框
public class HttpResponseListener<T> implements OnResponseListener { //使用自定义进度条对话框 private WaitDialog waitDialog; //使用自定义的监听方法的接口类 private HttpListener<T> callback; //一个标识,看是否在加载 private boolean isLoading; //一个Nohttp的队列 private Request> request; //构造方法 /** * context 上下文 * request Nohttp的队列
* callback 自定义一个NOhttp请求网络的监听器接口对象,调用其抽象方法,
以便实现接口时,只需覆写请求网络成功和请求网络失败的两个方法即可
* CanCancle 判断进度条对话框是否可以取消 * isLoding 判断进度条对话框是否是处在可以加载状态 */ public HttpResponseListener(Context context, Request> request, HttpListener< T> callback, boolean canCancle, boolean isLoading) { this. callback = callback; this. isLoading = isLoading; this. request = request; // 对上下文进行非空判断及判断进度条对话框是否显示 if (context != null && isLoading) { waitDialog = new WaitDialog(context); waitDialog.setCancelable(canCancle); // 当对话框点击外面可以取消,那么就让他取消掉的逻辑代码 waitDialog.setOnCancelListener( new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { HttpResponseListener. this. request.cancel(); } }); } } // 请求网络开始时回调,进度条对话框的显示 @Override public void onStart( int what) { // 判断进度条对话框是否处于加载状态,进度条对话框对象是否存在,进度条对话框是否显示 if ( isLoading && waitDialog != null && ! waitDialog.isShowing()) { waitDialog.show(); } } // 网络请求成功时回调,代码直接运行在主线程 @Override public void onSucceed( int what, Response response) { // 使用的是自己定义的接口,先判断接口对象是否为空,不为空,执行 if ( callback != null) { callback.onSucceed(what, response); } } // 网络请求失败时回调,代码直接运行到主线程 @Override public void onFailed( int what, Response response) { if ( callback != null) { callback.onFailed(what,response); } } // 请求网络结束时回调,进度条对话框隐藏 @Override public void onFinish( int what) { if ( isLoading && waitDialog != null && waitDialog.isShowing()) { waitDialog.dismiss(); } } } 五、 使用studio可以自动生成一个单例模式的类,该类不可以new出来,只能获取 .使用NOhttp请求网络时,得到该类对象, 调用该类方法即可,是封装NOhttp向外暴露的类。 代码如下:public class CallServer { private static CallServer callServer; /** * 通过类名调用,获取CallServer对象 */ public synchronized static CallServer getRequestIntance() { if (callServer == null) { callServer = new CallServer(); } return callServer; } /** * 创建Nohttp请求队列的对象 */ private RequestQueue requestQueue; private CallServer() { requestQueue = NoHttp.newRequestQueue(); }
/** 添加一个请求到队列
* @param context 上下文 用来实例化自定义的对话框
* @param request 请求对象
* @param what 用来标志请求
* @param callback 网络请求的监听器
* @param canCancle 是否同意用户请求取消
* @param isLoading 是否显示进度条对话框
* @param
*/
public < T> void add(Context context, int what, Request< T> request, HttpListener< T> callback, boolean canCancle, boolean isLoading) { requestQueue.add(what, request, new HttpResponseListener< T> (context, request, callback, canCancle, isLoading)); } } 六、封装之后,在Activity中使用 代码如下:public class MainActivity extends AppCompatActivity implements HttpListener, View.OnClickListener { private Button btnOk; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } @Override public void onSucceed(int what, Response response) { switch ( what){ case 0: Toast.makeText(MainActivity.this, ""+response.get(), Toast.LENGTH_SHORT).show(); break; } } @Override public void onFailed(int what, Response response) { switch ( what){ case 0: Toast.makeText(MainActivity.this, ""+response.get(), Toast.LENGTH_SHORT).show(); break; } } private void initView() { btnOk = (Button) findViewById(R.id.btnOk); btnOk.setOnClickListener(this); } //根据点击事件,使用Nohttp执行网络请求 @Override public void onClick(View v) { switch (v.getId()) { case R.id.btnOk: String url = "http://www.baidu.com"; //创建请求对象,设置加载的网络路径和请求 Requestrequest = NoHttp.createStringRequest(url, RequestMethod.GET); //获取核心的Nohttp网络工具类对象 CallServer callServerInstance = CallServer.getRequestIntance(); //把队列添加进去 callServerInstance.add(MainActivity.this,0,request,this,true,true); break; } } }
按照上面的步骤一步步的完成,即可完成效果图所示的效果。