Android项目开发全程(三)-- 项目的前期搭建、网络请求封装是怎样实现的
在前两篇博文中已经做了铺垫,下面咱们就可以用前面介绍过的内容开始做一个小项目了(项目中会用到Afinal框架,不会用Afinal的童鞋可以先看一下上一篇博文),正所谓麻雀虽小,五脏俱全,这在里我会尽量的将前期的项目搭建做的相对实用一些,以便后期可以有效的实现团队协作和项目维护。一开始可能会看起来麻烦些,可能会觉得还不如直接用简单的方式去实现来的方便,磨刀不误砍柴工嘛,要想后期开发效率高一些,前期就不要图省事了。
一个项目肯定不是一蹴而就的,咱们一步一步来,本篇博文先详细介绍项目搭建、通过url地址发送网络请求获取json数据。
先来看一下思路:
1、对Afinal中的get或者post方法进行一下封装,目的主要是不用每次请求时都再去写重复代码,并且如果有人员分工的话,各开发人员就可以公用封装好的方法。
2、提交url地址(接口)获取json字符串。
3、将获取到的字符串显示出来。
在这里我们使用360免费笑话接口:http://xiaohua.hao.360.cn/m/itxt(更新:现在已不能用了,抱歉!不过不影响参考思路)
一、首先创建工程,工程名:LaughDemo(在博文:《Android项目开发全程(一)--创建工程》中有介绍)
1、布局文件很简单,只有一个TextView用来显示获取的json数据(activity_main.xml)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <TextView 8 android:id="@+id/tv_show" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" /> 11 12 </LinearLayout>
2、创建一个常量接口(Constant.java)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 常量接口 3 * @author 刘伟 2015.7.3 4 * 5 */ 6 public interface Constants { 7 /* 请求方式 */ 8 String POST = "post"; 9 String GET = "get"; 10 11 /* 加载对话框指令码 */ 12 int DIALOG_SHOW = 1; 13 int DIALOG_CONCEL = 0; 14 15 /* 请求标识码--在响应结果用于区分不用响应 */ 16 int REQUEST_360LAUGH_CODE = 0000; 17 18 /* 请求地址 */ 19 String LAUGH_URL_360 = "http://xiaohua.hao.360.cn/m/itxt"; 20 }
3、创建一个回调接口,让需要做网络请求的Activity实现此接口(DataCallBack.java)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 回调接口 3 * @author 刘伟 2015.7.3 4 * 5 */ 6 public interface DataCallBack { 7 public void onCallBackSuccessed(int notify, String result);//请求响应成功时回调 8 public void onCallBackFailed(int notify);//请求响应失败时回调 9 }
4、创建一个基类(BaseActivity.java),将一些共同的工作放在里面,这里的基类初始化了一个加载对话框(对话框代码布局代码比较简单,就不贴了)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 基类 3 * @author 刘伟 2015.7.3 4 * 5 */ 6 public class BaseActivity extends FinalActivity implements Constants { 7 private Dialog dialog; 8 protected Handler mHandler = new Handler(){ 9 10 public void handleMessage(Message msg) { 11 if(msg.what == DIALOG_SHOW){ 12 dialog.show(); 13 } else { 14 dialog.cancel(); 15 } 16 }; 17 }; 18 @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 //创建并初始化加载对话框 22 dialog = new Dialog(this, R.style.dialogTheme); 23 dialog.setContentView(R.layout.loaddialog); 24 dialog.setCanceledOnTouchOutside(true); 25 } 26 }
5、创建一个网络请求工具类(HttpRequest.java),将网络请求方法进行封装。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.laughdemo.http; 2 import java.util.Map; 3 import net.tsz.afinal.FinalHttp; 4 import net.tsz.afinal.http.AjaxCallBack; 5 import net.tsz.afinal.http.AjaxParams; 6 import com.laughdemo.utils.Constants; 7 /** 8 * 网络请求工具类 9 * @author 刘伟 2015.7.3 10 * 11 */ 12 public class HttpRequest implements Constants { 13 private final String TAG = "HttpRequest"; 14 private FinalHttp fh; 15 private DataCallBack dataCallBack; 16 17 public HttpRequest(DataCallBack dataCallBack){ 18 fh = new FinalHttp(); 19 this.dataCallBack = dataCallBack; 20 } 21 22 public void requestPost(int requestCode, Map<String, String> map, String url){ 23 requestData(requestCode, map, url, POST); 24 } 25 26 public void requestGet(int requestCode, Map<String, String> map, String url){ 27 requestData(requestCode, map, url, GET); 28 } 29 30 //封装网络请求方法 31 private void requestData(int requestCode, Map<String, String> map, String url, String requestMothed){ 32 String httpUrl = url; 33 34 if("get".equals(requestMothed)){ 35 //get请求 36 String urlParam = ""; 37 if (!url.contains("?")) 38 httpUrl += "?"; 39 else 40 httpUrl += "&"; 41 int i = map.size(); 42 for(String key: map.keySet()){ 43 i--; 44 urlParam += key + "=" + map.get(key); 45 if(i > 0){ 46 urlParam += "&"; 47 } 48 } 49 httpUrl += urlParam; 50 System.out.println(TAG + ":get:" + httpUrl); 51 fh.get(httpUrl, new HttpListener(requestCode, dataCallBack)); 52 } else { 53 //post请求 54 System.out.println(TAG + ":post-httpUrl:" + httpUrl); 55 System.out.println(TAG + ":post-httpUrl-map:" + map); 56 AjaxParams ap = new AjaxParams(map); 57 fh.post(httpUrl, ap, new HttpListener(requestCode, dataCallBack)); 58 } 59 60 } 61 62 /** 63 * Afinal回调 64 * @author lw 65 * 66 */ 67 class HttpListener extends AjaxCallBack<String>{ 68 69 private int notify; 70 private DataCallBack dataCallBack; 71 72 public HttpListener(int notify, DataCallBack dataCallBack){ 73 this.notify = notify; 74 this.dataCallBack = dataCallBack; 75 } 76 77 @Override 78 public void onSuccess(String t) { 79 // TODO Auto-generated method stub 80 System.out.println(TAG + ":" + t); 81 if(this.dataCallBack != null){ 82 /** 执行onCallBackSuccessed()回调方法 */ 83 this.dataCallBack.onCallBackSuccessed(notify, t); 84 } 85 } 86 @Override 87 public void onFailure(Throwable t, int errorNo, String strMsg) { 88 // TODO Auto-generated method stub 89 if(this.dataCallBack != null){ 90 /** 执行onCallBackFailed()回调方法 */ 91 this.dataCallBack.onCallBackFailed(notify); 92 } 93 } 94 } 95 }
6、创建一个提交网络地址类(GetNetData.java),将不同的地址提交方法放在此类下。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.laughdemo.http; 2 import java.util.HashMap; 3 import java.util.Map; 4 import com.laughdemo.utils.Constants; 5 /** 6 * 获取网络数据类 7 * @author 刘伟 2015.7.3 8 * 9 */ 10 public class GetNetData implements Constants { 11 12 private HttpRequest httpRequest; 13 14 public GetNetData(DataCallBack dataCallBack){ 15 this.httpRequest = new HttpRequest(dataCallBack); 16 } 17 18 //360笑话接口请求方法 19 public void getLaughBy360(int requestCode, String pageNo){ 20 Map<String, String> map = new HashMap<String, String>(); 21 map.put("page", pageNo); 22 httpRequest.requestPost(requestCode, map, LAUGH_URL_360); 23 } 24 25 //其他接口请求方法... 26 }
7、最后一个类了,主窗体类(MainActivity.java),与用户交互,调用GetNetData.java中的getLaughBy方法获取json字符串,然后在tvShow展示。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.laughdemo.main; 2 import net.tsz.afinal.annotation.view.ViewInject; 3 import android.os.Bundle; 4 import android.widget.TextView; 5 import android.widget.Toast; 6 import com.laughdemo.http.DataCallBack; 7 import com.laughdemo.http.GetNetData; 8 import com.laughdemo.utils.Constants; 9 /** 10 * 主窗体类 11 * @author 刘伟 2015.7.3 12 * 13 */ 14 public class MainActivity extends BaseActivity implements Constants, DataCallBack{ 15 final String TAG = "MainActivity"; 16 GetNetData getNetData; 17 @ViewInject(id=R.id.tv_show) TextView tvShow; 18 @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.activity_main); 22 getNetData = new GetNetData(this); 23 getNetData.getLaughBy360(REQUEST_360LAUGH_CODE, "1"); 24 mHandler.sendEmptyMessage(DIALOG_SHOW); 25 } 26 @Override 27 public void onCallBackSuccessed(int notify, String result) { 28 mHandler.sendEmptyMessage(DIALOG_CONCEL); 29 if(notify == REQUEST_360LAUGH_CODE){ 30 tvShow.setText(result); 31 } 32 } 33 @Override 34 public void onCallBackFailed(int notify) { 35 Toast.makeText(getApplicationContext(), "网络连接失败", Toast.LENGTH_LONG).show(); 36 } 37 }
OK,果断上图看效果
由图分析:
1、程序启动后会调用getLaughBy360()方法做网络请求。
2、同时会通过mHandler.sendEmptyMessage()发送消息显示加载对话框。
3、请求成功后回调onCallBackSuccessed(),获取json字符串并隐藏加载对话框。
4、最后一步匹配请求码,并显示json字符串。
现在获取到的json字符看起来像是一顿乱码,这正是我们想要的,我们后续要做的工作就是解析这些“乱码”,然后让它们有规则的显示到listview中,等整个项目完成后本人会把代码上传并附上下载链接(现在还没完成暂不能上传),今天先更新到这里,后续博文将会详细介绍解析全程。
注:转载时请附上本文链接。
作者:CodingBlock
出处:http://www.cnblogs.com/codingblock/
本文版权归作者和共博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如果文中有什么错误,欢迎指出。以免更多的人被误导。