Android AsyncTask异步加载WebAPI
之前做的程序一直存在很多问题,因为需要加载的Activity需要从网络加载数据。并没有完全正确的使用异步的方法去加载!
之前用的虽然是AsyncTask,但是在加载完成的时候还是并没有使用AsyncTask内置的方法去处理。而已傻傻的在OnCreate中处理。结果还是要等待AsyncTask加载完成后,等待OnCreate执行完成后,才load到Activity。这样子给人的第一感觉就是卡机了一样!
果断重新再写,这次的代码真是大换血。首先还是选择把带分页ListView进行封装了一下。
- import com.sf.campus.R;
- import android.app.Activity;
- import android.os.Handler;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.BaseAdapter;
- import android.widget.Button;
- import android.widget.ListAdapter;
- import android.widget.ListView;
- import android.widget.Toast;
- /**
- * 模版化的ListView
- * @author Administrator
- *
- */
- public class ListViewPageTemplate {
- private View loadMoreView; //用来显示加载更多的一个视图
- private Button loadMoreButton; //视图中的按钮
- private int datasize; // 记录已有数据条数
- private int pageindex = 1;// 页面的位置,若没有传入则默认为1
- private int pagesize = 3; //每页显示的数量
- private Activity activity;//当前的Activity
- private ListView myList;//当前page使用的List
- private ListAdapter myAdapter = null;//用来传输数据
- private Handler handler = new Handler();
- private OnExcuteListener onExcuteListener;
- public interface OnExcuteListener{
- void excute();
- }
- private static final String TAG="Informacation";
- /**
- * 构造函数
- * @param activity 上下文的Activity
- * @param myList 用来显示的ListView
- */
- public ListViewPageTemplate(Activity activity, ListView myList) {
- super();
- this.activity = activity;
- this.myList = myList;
- init();
- }
- private void init(){
- Log.i(TAG, "[page] begin init");
- loadMoreView = activity.getLayoutInflater().inflate(R.layout.loadmore, null);
- loadMoreButton = (Button) loadMoreView.findViewById(R.id.loadMoreButton);
- myList.addFooterView(loadMoreView); //设置列表底部视图
- initLoadMore();
- Log.i(TAG, "[page] end init");
- }
- /**
- * 点击加载更多
- */
- private void initLoadMore(){
- loadMoreButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- pageindex++;
- loadMoreButton.setText("正在加载中...");
- handler.postDelayed(new Runnable() {
- public void run() {
- loadMoreData();
- ((BaseAdapter) myAdapter).notifyDataSetChanged();
- loadMoreButton.setText("查看更多..."); //恢复按钮文字
- }
- },3000);
- }
- });
- }
- /**
- * 加载数据,更新ListView
- */
- private void loadMoreData(){
- int count = myAdapter.getCount();
- if(count+pagesize < datasize){
- if(onExcuteListener!= null)
- onExcuteListener.excute();
- else{
- Log.i(TAG, "[page] onExcuteListener is null");
- }
- }else{
- if(onExcuteListener!= null)
- onExcuteListener.excute();//已经加载完成
- else{
- Log.i(TAG, "[page] onExcuteListener is null");
- }
- ((BaseAdapter) myAdapter).notifyDataSetChanged();
- myList.removeFooterView(loadMoreView);
- alert("已加载完成!");
- }
- }
- public void alert (String msg)
- {
- Toast.makeText(activity.getApplicationContext(), msg, Toast.LENGTH_LONG).show();
- }
- public int getDatasize() {
- return datasize;
- }
- public void setDatasize(int datasize) {
- this.datasize = datasize;
- }
- public int getPageindex() {
- return pageindex;
- }
- public void setPageindex(int pageindex) {
- this.pageindex = pageindex;
- }
- public int getPagesize() {
- return pagesize;
- }
- public void setPagesize(int pagesize) {
- this.pagesize = pagesize;
- }
- public ListView getMyList() {
- return myList;
- }
- public void setMyList(ListView myList) {
- this.myList = myList;
- }
- public ListAdapter getMyAdapter() {
- return myAdapter;
- }
- public void setMyAdapter(ListAdapter myAdapter) {
- this.myAdapter = myAdapter;
- }
- public OnExcuteListener getOnExcuteListener() {
- return onExcuteListener;
- }
- public void setOnExcuteListener(OnExcuteListener onExcuteListener) {
- this.onExcuteListener = onExcuteListener;
- }
- }
我这里封装的ListView主要还有一个加载点击后要触发的事件,发现在类里面写个接口挺好的。
整个ListViewPageTemplate类,主要有ListView和Adapter,还有pagesize,pageindex,datasize等一些判断分页的参数。
接下来就是使用了,首先初始化一下。
- private ListViewPageTemplate listViewTemplate = null;
- private ListView messageCenterList;
- private List<MessageCenter> messageCenters;//ListView显示的数据
- messageCenterList = (ListView) this.findViewById(R.id.listViewMessageCenter);
- messageCenters = new ArrayList<MessageCenter>();
- listViewTemplate = new ListViewPageTemplate(MessageCenterListActivity.this , messageCenterList);
然后当前Activity需要实现ListViewPageTemplate.OnExcuteListener接口。
- listViewTemplate.setOnExcuteListener(this);
- @Override
- public void excute() {
- MessageCenterTask task = new MessageCenterTask();
- try {
- Log.i("Informacation", "begin excute");
- /**
- * 异步处理的类
- */
- task.execute();
- Log.i("Informacation", "end excute");
- }
- catch (Exception e)
- {
- task.cancel(true);
- }
- }
MessageCenterTask一开始是写在别的类里面,后来发现他要用到ListView用到,ListView中的数据和Adapter。然后继承AsyncTask的类实现的doInBackground只能被调用一次,发现又写不下去了于是索性把MessageCenterTask写到Activity类的内部作为内部类存在。发现可用!哈哈!
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.http.NameValuePair;
- import org.apache.http.message.BasicNameValuePair;
- import com.sf.campus.adapter.MessageCenterAdapter;
- import com.sf.campus.dao.MessageCenterDAO;
- import com.sf.campus.models.MessageCenter;
- import com.sf.campus.models.MessageCenterJsonBean;
- import com.sf.campus.utils.ConstantService;
- import com.sf.campus.utils.JSONHttpClient;
- import com.sf.campus.utils.ListViewPageTemplate;
- import com.sf.campus.utils.WifiService;
- import android.app.Activity;
- import android.os.AsyncTask;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.BaseAdapter;
- import android.widget.LinearLayout;
- import android.widget.ListAdapter;
- import android.widget.ListView;
- import android.widget.TextView;
- import android.widget.Toast;
- public class MessageCenterListActivity extends Activity implements ListViewPageTemplate.OnExcuteListener{
- private ListView messageCenterList;
- private ListAdapter adapter;
- private ListViewPageTemplate listViewTemplate = null;
- private List<MessageCenter> messageCenters;//ListView显示的数据
- private boolean isFirstPage = true;
- private static final String TAG="Informacation";
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- Log.i(TAG, "onCreate");
- super.onCreate(savedInstanceState);
- setContentView(R.layout.messagecenter_list);
- messageCenterList = (ListView) this.findViewById(R.id.listViewMessageCenter);
- messageCenters = new ArrayList<MessageCenter>();
- /**
- * 与界面相关包含ListView实现一些分页功能
- */
- listViewTemplate = new ListViewPageTemplate(MessageCenterListActivity.this , messageCenterList);
- Log.i(TAG, "对象已经初始化完成!");
- }
- @Override
- protected void onStart() {
- super.onStart();
- if (new WifiService(MessageCenterListActivity.this).isNetworkConnected() == true) {
- Log.e("Informacation", "网络加载");
- excute();
- } else {
- Log.e("Informacation", "本地加载");
- // 如果没有网络则直接加载本地数据
- loadDataForLocal();
- }
- listViewTemplate.setOnExcuteListener(this);
- setTitle();
- addTitleBack();
- }
- public void alert (String msg)
- {
- Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
- }
- /**
- * 加载本地数据
- */
- public void loadDataForLocal() {
- MessageCenterDAO dao = new MessageCenterDAO(getApplicationContext());
- List<MessageCenter> mcs = dao.getScrollData(0, 8);
- if( messageCenters != null ){
- listViewTemplate.setDatasize(Integer.valueOf(mcs.get(0).getDatasize()));
- adapter = new MessageCenterAdapter(LayoutInflater.from(MessageCenterListActivity.this), mcs);
- listViewTemplate.setMyAdapter(adapter);
- listViewTemplate.getMyList().setAdapter(listViewTemplate.getMyAdapter());
- }else{
- Log.i(TAG, "[Method:loadDataForLocal] messageCenterList is null");
- }
- }
- /**
- * 保存到本地
- * @param messageCenters
- */
- public void save(List<MessageCenter> messageCenters){
- MessageCenterDAO dao = new MessageCenterDAO(getApplicationContext());
- dao.deleteAll();
- for(MessageCenter mc : messageCenters){
- dao.save(mc);
- }
- }
- @Override
- public void excute() {
- MessageCenterTask task = new MessageCenterTask();
- try {
- Log.i("Informacation", "begin excute");
- /**
- * 提供常用CURD及数据获取的类
- */
- task.execute();
- Log.i("Informacation", "end excute");
- }
- catch (Exception e)
- {
- task.cancel(true);
- }
- }
- /**
- * adapter的一些字段
- * @author Administrator
- *
- */
- public static class MessageCenterRowHolder {
- public TextView messageCenterId, messageCenterTitle;
- public MessageCenter messageCenter;
- }
- /**
- * 设置标题
- */
- private void setTitle(){
- TextView tv = (TextView) this.findViewById(R.id.title_text);
- tv.setText("消息中心");
- }
- /**
- * 返回事件
- */
- private void addTitleBack(){
- LinearLayout layout= (LinearLayout) this.findViewById(R.id.title_back);
- layout.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- MessageCenterListActivity.this.finish();
- }
- });
- }
- /**
- *
- * @author Administrator
- *
- */
- class MessageCenterTask extends AsyncTask<String, String, List<MessageCenter>>{
- String URL= ConstantService.HEAD + ConstantService.SCHOOL + ConstantService.MESSAGECENTER_SERVICE_URL;
- private List<NameValuePair> createNameValuePairs(){
- Log.i(TAG, "userId=" + String.valueOf( ConstantService.userID ) +
- "pageIndex="+ String.valueOf( listViewTemplate.getPageindex()) +
- "pageSize" + String.valueOf(listViewTemplate.getPagesize()));
- List<NameValuePair> list = new ArrayList<NameValuePair>();
- NameValuePair p1 = new BasicNameValuePair("userId", String.valueOf( ConstantService.userID ) );
- NameValuePair p2 = new BasicNameValuePair("pageIndex", String.valueOf( listViewTemplate.getPageindex() ) );
- NameValuePair p3 = new BasicNameValuePair("pageSize" , String.valueOf(listViewTemplate.getPagesize()));
- NameValuePair p4 = new BasicNameValuePair("format" , "json");
- list.add(p1);
- list.add(p2);
- list.add(p3);
- list.add(p4);
- return list;
- }
- /**
- * 这里的Integer参数对应AsyncTask中的第一个参数
- * 这里的String返回值对应AsyncTask的第三个参数
- * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改
- * 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作
- */
- @Override
- protected List<MessageCenter> doInBackground(String... arg0) {
- Log.i(TAG, "Task Start");
- List<NameValuePair> pairs = createNameValuePairs();
- List<MessageCenter> mcs= new ArrayList<MessageCenter>();
- JSONHttpClient client= new JSONHttpClient();
- MessageCenterJsonBean result= client.Get(URL, pairs, MessageCenterJsonBean.class );
- //存储页面的大小
- listViewTemplate.setDatasize(result.getTotal());
- for(int i=0; i<result.getRows().size(); i++){
- MessageCenter messageCenter = new MessageCenter();
- messageCenter.setID(result.getRows().get(i).getID());
- messageCenter.setTitle(result.getRows().get(i).getTitle());
- messageCenter.setContent(result.getRows().get(i).getContent());
- mcs.add(messageCenter);
- }
- Log.i(TAG, "Task End");
- return mcs;
- }
- /**
- * 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)
- * 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置
- */
- @Override
- protected void onPostExecute(List<MessageCenter> result) {
- loadDataForNet(result);
- super.onPostExecute(result);
- }
- /**
- * 加载网络数据
- * @param result
- */
- private void loadDataForNet(List<MessageCenter> result) {
- if(result != null)
- {
- //若是第一页则保存到本地
- if(isFirstPage){
- Log.i(TAG, "第一次加载!");
- save(result);
- messageCenters.clear();
- messageCenters.addAll(result);
- adapter = new MessageCenterAdapter(LayoutInflater.from(MessageCenterListActivity.this), messageCenters);
- listViewTemplate.setMyAdapter(adapter);
- listViewTemplate.getMyList().setAdapter(listViewTemplate.getMyAdapter());
- //listViewTemplate.setMyAdapter(adapter);
- isFirstPage = false;
- }else{
- Log.i(TAG, "不是第一次加载!更新!");
- messageCenters.addAll(result);
- ((BaseAdapter) adapter).notifyDataSetChanged();
- }
- }
- else
- {
- Log.i(TAG, "[Method:loadDataForNetFirst] messageCenterList is null");
- }
- }
- }
- }
算是实现了,真是不容易啊!感谢DevinZhang博主的一篇文章android AsyncTask介绍
从其中学到了很多新的知识点,非常的感谢!
Android AsyncTask异步加载WebAPI的更多相关文章
- Android开发--异步加载
因为移动端软件开发思维模式或者说是开发的架构其实是不分平台和编程语言的,就拿安卓和IOS来说,他们都是移动前端app开发展示数据和用户交互数据的数据终端,移动架构的几个大模块:UI界面展示.本地数据可 ...
- [Android] Android 用于异步加载 ContentProvider 中的内容的机制 -- Loader 机制 (LoaderManager + CursorLoader + LoaderManager.LoaderCallbacks)
Android 用于异步加载 ContentProvider 中的内容的机制 -- Loader 机制 (LoaderManager + CursorLoader + LoaderManager.Lo ...
- Android 图片异步加载的体会,SoftReference已经不再适用
在网络上搜索Android图片异步加载的相关文章,目前大部分提到的解决方案,都是采用Map<String, SoftReference<Drawable>> 这样软引用的 ...
- Android图片异步加载之Android-Universal-Image-Loader
将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...
- Android图片异步加载之Android-Universal-Image-Loader(转)
今天要介绍的是Github上一个使用非常广泛的图片异步加载库Android-Universal-Image-Loader,该项目的功能十分强大,可以说是我见过的目前功能最全.性能最优的图片异步加载解决 ...
- android 网络异步加载数据进度条
ProgressDialog progressDialog = null; public static final int MESSAGETYPE = 0; private void execute( ...
- Android 之异步加载LoaderManager
LoaderManager: Loader出现的背景: Activity是我们的前端页面展现,数据库是我们的数据持久化地址,那么正常的逻辑就是在展示页面的渲染页面的阶段进行数据库查询.拿到数据以后才展 ...
- Android GridView异步加载图片和加载大量图片时出现Out Of Memory问题
我们在使用GridView或者ListView时,通常会遇到两个棘手的问题: 1.每个Item获取的数据所用的时间太长会导致程序长时间黑屏,更甚会导致程序ANR,也就是Application No R ...
- android listview 异步加载图片并防止错位
网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertVie ...
随机推荐
- java-04流程控制语句
这里先简单介绍几种流程控制语句 包括if/if-else.switch语句 1.三大流程控制结构 所谓流程控制,就是说要控制程序的执行方式,根据不同的情况执行不同的代码,从而得到不同情况下的不同结果. ...
- Conditional Expressions
Conditional Expressions建立一些逻辑关系 The conditional expression classes from django.db import models clas ...
- windows Win7如何设置多用户同时远程登录
windows Win7如何设置多用户同时远程登录 1.创建一个用户 密码永不过期 2.在本地组策略编辑器里面,依次展开计算机配置--->管理模板--->Windows组件---> ...
- 小程序:怎么在两层列表循环(wx:for)的时候判断是否为最后一个元素
问题说明: 如下图所示,在箭头所指的最后一个选项的底线与底部操作栏的上边线重叠,需要清除掉最后一个元素的底线: 想到的解决方案: 通过判断是否为最后一个元素,然后通过条件渲染(wx:if)动态添加对 ...
- (1)python的基础认知
Python程序员的信仰:人生苦短,我用python! (一)python的发展史 1989年开发的语言,创始人范罗苏姆(Guido van Rossum),别称:龟叔(Guido).为了打发圣诞节假 ...
- Sublime Text3 最新版3207 安装及破解
注:原文地址 https://www.abbeyok.com/archives/337 Sublime Text 3最近更新了新版本,最新版本:3207,之前的license无效了,新版破解方法如下: ...
- Redis数据持久化,安全
一.redis数据持久化 由于redis是一个内存数据库,如果系统遇到致命问题需要关机或重启,内存中的数据就会丢失,这是生产环境所不能允许的.所以redis提供了数据持久化的能力. redis提供了两 ...
- [ActionScript 3.0] 使用Embed在类中嵌入字体
package { import flash.display.Sprite; import flash.text.Font; import flash.text.TextField; import f ...
- Linux系统如何迁移至LVM磁盘
今天遇到一个问题,算是比较严重的把.就是要把当前系统转移到 LVM 卷里面去,下面有一些发生过程介绍. 不感兴趣可以直接跳过,看实战部分<如何迁移系统至LVM卷> 朋友今天突然找我,说是要 ...
- CentOS 中卸载 RPM 包文件
CentOS 中卸载 RPM 包文件 一.原由 因为之前卸载 openvas 这个工具,使用了 find / -name "openvas"-exec rm -rf {} \ ; ...