开源中国源码学习数据篇(一)之android-async-http框架和AsyncTask
来源:互联网 发布:白凡泄露天机知乎 编辑:程序博客网 时间:2024/06/05 09:45
今天来进行数据(从开源中国服务器上面get新闻信息)的联网获取,关键步骤就是应用android-async-http框架,输入向服务器post的参数,异步获得服务器的数据。接着异步解析成adapter可以用的ListEntity<T>格式,在ListView中展示出来。
一、定义基类ListBaseAdapter文件
核心数据是mDatas,后面的关键代码就是从服务器获取数据,并将XML异步解析,添加到mDatas中,最后在ListView中展示。获取服务器数据用到了android-async-http框架。这个ListBaseAdapter文件用于存放ListView数据适配的公共方法。
protected ArrayList<T> mDatas = new ArrayList<T>();@Override public int getCount() { return getDataSize(); } @Override public Object getItem(int pos) { if(mDatas.size()>pos) return mDatas.get(pos); return null; } @SuppressWarnings("deprecation") @SuppressLint("InflateParams") @Override public View getView(int pos, View convertView, ViewGroup parent) { return getRealView(pos, convertView, parent); } public int getDataSize() { return mDatas.size(); } protected View getRealView(int position, View convertView, ViewGroup parent) { return null; } public ArrayList<T> getData() { return mDatas == null ? (mDatas = new ArrayList<T>()) : mDatas; }//将转换的数据,添加到mDatas public void addData(List<T> data) { if (mDatas != null && data != null && !data.isEmpty()) { mDatas.addAll(data); } notifyDataSetChanged(); Log.i("a", "ss"); }
二、展示新闻数据的适配文件-NewsAdapter
继承于ListBaseAdapter,具体的对layout中的控件进行赋值。
@SuppressLint("InflateParams") @Override protected View getRealView(int position, View convertView, ViewGroup parent) { ViewHolder vh = null; if (convertView == null || convertView.getTag() == null) { convertView = getLayoutInflater(parent.getContext()).inflate( R.layout.list_cell_news, null); vh = new ViewHolder(convertView); convertView.setTag(vh); } else { vh = (ViewHolder) convertView.getTag(); } News news = mDatas.get(position); vh.title.setText(news.getTitle()); //给里面的各个控件赋值 ………………………………………………………}
三、Fragment类型文件的界面-BaseListFragment
1、概述
下面为BaseListFragment文件的代码:
public abstract class BaseListFragment<T extends Entity> extends BaseFragment implements OnItemClickListener, OnScrollListener,SwipeRefreshLayout.OnRefreshListener { @InjectView(R.id.listview) protected ListView mListView; protected ListBaseAdapter<T> mAdapter; protected abstract ListBaseAdapter<T> getListAdapter(); private ParserTask mParserTask; @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ButterKnife.inject(this, view); //初始化界面 initView(view); } @Override public void initView(View view) { mSwipeRefreshLayout.setOnRefreshListener(this); mListView.setOnItemClickListener(this); mListView.setOnScrollListener(this); if (mAdapter != null) { mListView.setAdapter(mAdapter); } else { //根据不同的list 不同子类有不同geiListAdapter的实现 mAdapter = getListAdapter(); mListView.setAdapter(mAdapter); //获取数据地方 requestData(false); } }
2、定义handler处理服务器传回的数据
接收请求结果,一般重写onSuccess及onFailure接收请求成功或失败的消息,还有onStart,onFinish等消息。当接收到服务器传来的信息后,如果成功调用 executeParserTask(responseBytes)方法。向服务器post数据的操作、android-async-http框架的使用在后面介绍,数据请求在NewsFragment文件中执行。
protected AsyncHttpResponseHandler mHandler = new AsyncHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBytes) { executeParserTask(responseBytes); }}private void executeParserTask(byte[] data) { cancelParserTask(); mParserTask = new ParserTask(data); mParserTask.execute(); }
3、继承于AsyncTask的异步解析任务-ParserTask
- doInBackground(Params…) 后台执行,用来写耗时操作,但这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以 调用publicProgress(Progress…)来更新任务的进度。
- onPostExecute(Result) 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回
class ParserTask extends AsyncTask<Void, Void, String> { private final byte[] reponseData; private boolean parserError; private List<T> list;//从服务器获取的数据保存在形参中,传进来赋值给responseData public ParserTask(byte[] data) { this.reponseData = data; } @Override protected String doInBackground(Void... params) { try { //解析数据为ListEntity格式 ListEntity<T> data = parseList(new ByteArrayInputStream( reponseData)); list = data.getList(); } catch (Exception e) { e.printStackTrace(); parserError = true; } return null; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); //将数据赋值到mAdapter,在ListView中展示 mAdapter.addData(data); } }
四、新闻获取展示界面-NewsFragment
1、概述
根据类的不同,这里发出向服务器获取数据的请求,赋值不同的adapter(这里为NewsAdapter)。因为BlogFragment(从服务器获取博客数据)和NewsFragment同继承于BaseListFragment<T>,所以该类要反映出它们的差异。
/** * @function 综合-资讯/热点界面 */public class NewsFragment extends BaseListFragment<News> { protected static final String TAG = NewsFragment.class.getSimpleName(); //之前使用的是 在外部定义adapter作为参数传进来 @Override protected ListBaseAdapter<News> getListAdapter() { return new NewsAdapter(); } //解析List @Override protected NewsList parseList(InputStream is) throws Exception { NewsList list = null; try { list = XmlUtils.toBean(NewsList.class, is); } catch (NullPointerException e) { list = new NewsList(); } return list; } @Override protected void sendRequestData() { //mHandler在BaseListFragment中定义,mHandler监测从服务器中获取的数据 OSChinaApi.getNewsList(mCatalog, mCurrentPage, mHandler); }}
2、定义用于传递参数获取数据的接口
为获取新闻制定接口。
/** * 获取新闻列表 * @param catalog * 类别 (1,2,3) * @param page * 第几页 * @param handler */ public static void getNewsList(int catalog, int page, AsyncHttpResponseHandler handler) { RequestParams params = new RequestParams(); params.put("catalog", catalog); params.put("pageIndex", page); params.put("pageSize", 20);//默认分页 if (catalog == NewsList.CATALOG_WEEK) { params.put("show", "week"); } else if (catalog == NewsList.CATALOG_MONTH) { params.put("show", "month"); } //第一个参数为相对地址 ApiHttpClient.get("action/api/news_list", params, handler); }
3、Android-Async-Http架构的使用
Android- Async-Http的使用非常简单,通过AsyncHttpClient发起请求就可以了,如果需要添加参数,直接传一个RequestParams过 去,而且参数可以是String、File和InputStream,可以很方便地上传文件。在上面的接口,就是用于为AsyncHttpClient准备的。
每个请求都需要传一个ResponseHandlerInterface的实例用以接收请求结果或请求失败,请求结束等通知,一般是AsyncHttpResponseHandler的子类。
基本用法:
AsyncHttpClient client = new AsyncHttpClient();client.get("http://www.google.com", new AsyncHttpResponseHandler() { @Override public void onSuccess(String response) { System.out.println(response); }});
开源中国源码中,将AsyncHttpResponseHandler的就收请求结果放到了BaseListFragment中,前面介绍过。
public class ApiHttpClient { public static AsyncHttpClient client; private static String API_URL = "http://www.oschina.net/%s"; public final static String HOST = "www.oschina.net"; public static void get(String partUrl, AsyncHttpResponseHandler handler) { //一般的方法中handler为 new AsyncHttpResponseHandler() client.get(getAbsoluteApiUrl(partUrl), handler); log(new StringBuilder("GET ").append(partUrl).toString()); } /* * 到时候注意handler的触发和来源 */ public static void get(String partUrl, RequestParams params, AsyncHttpResponseHandler handler) { client.get(getAbsoluteApiUrl(partUrl), params, handler); log(new StringBuilder("GET ").append(partUrl).append("&") .append(params).toString()); } public static String getAbsoluteApiUrl(String partUrl) { String url = String.format(API_URL, partUrl); Log.d("BASE_CLIENT", "request:" + url); return url; }//配置网络信息 public static void setHttpClient(AsyncHttpClient c) { client = c; client.addHeader("Accept-Language", Locale.getDefault().toString()); client.addHeader("Host", HOST); client.addHeader("Connection", "Keep-Alive"); client.getHttpClient().getParams() .setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true); setUserAgent(ApiClientHelper.getUserAgent(AppContext.getInstance())); }}
4、存储系统信息的全局类-AppContext
AppContext类继承于Application,Application是android框架的一个系统组件,当android程序启动时系统会创建一个 application对象,用来存储系统的一些信息。android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例 (singleton)模式的一个类.且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。 在这里初始化网络请求。
public class AppContext extends BaseApplication{//BaseApplication继承于Application private static AppContext instance; @Override public void onCreate() { super.onCreate(); instance = this; init(); } private void init() { // 初始化网络请求 AsyncHttpClient client = new AsyncHttpClient(); ApiHttpClient.setHttpClient(client); }}
demo图片展示,就这一个界面。demo地址 开源中国源码学习数据篇(一)之android-async-http框架和AsyncTask。
Android- Async-Http的使用非常简单,通过AsyncHttpClient发起请求就可以了,如果需要添加参数,直接传一个RequestParams过 去,而且参数可以是String、File和InputStream,可以很方便地上传文件。在上面的接口,就是用于为AsyncHttpClient准备的。
每个请求都需要传一个ResponseHandlerInterface的实例用以接收请求结果或请求失败,请求结束等通知,一般是AsyncHttpResponseHandler的子类。
基本用法:
AsyncHttpClient client = new AsyncHttpClient();client.get("http://www.google.com", new AsyncHttpResponseHandler() { @Override public void onSuccess(String response) { System.out.println(response); }});
public class ApiHttpClient { public static AsyncHttpClient client; private static String API_URL = "http://www.oschina.net/%s"; public final static String HOST = "www.oschina.net"; public static void get(String partUrl, AsyncHttpResponseHandler handler) { //一般的方法中handler为 new AsyncHttpResponseHandler() client.get(getAbsoluteApiUrl(partUrl), handler); log(new StringBuilder("GET ").append(partUrl).toString()); } /* * 到时候注意handler的触发和来源 */ public static void get(String partUrl, RequestParams params, AsyncHttpResponseHandler handler) { client.get(getAbsoluteApiUrl(partUrl), params, handler); log(new StringBuilder("GET ").append(partUrl).append("&") .append(params).toString()); } public static String getAbsoluteApiUrl(String partUrl) { String url = String.format(API_URL, partUrl); Log.d("BASE_CLIENT", "request:" + url); return url; }//配置网络信息 public static void setHttpClient(AsyncHttpClient c) { client = c; client.addHeader("Accept-Language", Locale.getDefault().toString()); client.addHeader("Host", HOST); client.addHeader("Connection", "Keep-Alive"); client.getHttpClient().getParams() .setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true); setUserAgent(ApiClientHelper.getUserAgent(AppContext.getInstance())); }}
4、存储系统信息的全局类-AppContext
public class AppContext extends BaseApplication{//BaseApplication继承于Application private static AppContext instance; @Override public void onCreate() { super.onCreate(); instance = this; init(); } private void init() { // 初始化网络请求 AsyncHttpClient client = new AsyncHttpClient(); ApiHttpClient.setHttpClient(client); }}
- 开源中国源码学习数据篇(一)之android-async-http框架和AsyncTask
- Android 开源框架之 Android-async-http 源码解读
- Android 开源框架之 Android-async-http 源码解读
- Android 开源框架之 Android-async-http 源码解读
- android开源框架android-async-http学习笔记一
- android AsyncTask和HttpURLConnection结合,简单模仿android开源框架andorid-async-http
- android-async-http开源框架学习
- android-async-http源码解读(一)
- 使用开源框架android-async-http提交数据
- Android开源框架android-async-http的学习
- android-async-http框架之与服务器进行数据交互
- 开源框架android-async-http使用
- 开源框架android-async-http使用
- 开源框架android-async-http使用
- 开源框架android-async-http使用
- android-async-http开源框架的详细解释(附源码HTTP)
- android-async-http框架库源码走读
- android-async-http框架源码分析
- 登录Google账号
- 1002 A+B for Ploynomials
- 数据库SQL优化大总结之 百万级数据库优化方案
- 二级指针作为函数参数申请内存
- 回调
- 开源中国源码学习数据篇(一)之android-async-http框架和AsyncTask
- VMware下安装Mac系统
- 自定义SwitchPreference时遇到的问题
- 51nod 1024 矩阵中不重复的元素 (STL)
- android 蓝牙断开监听
- assert()函数用法
- PAT-PAT (Advanced Level) Practise 1012 The Best Rank (25) (简单模拟)【二星级】
- HDOJ 2540 遮挡判断(数学)
- mongodb 性能测试