之前做的程序一直存在很多问题,因为需要加载的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的更多相关文章

  1. Android开发--异步加载

    因为移动端软件开发思维模式或者说是开发的架构其实是不分平台和编程语言的,就拿安卓和IOS来说,他们都是移动前端app开发展示数据和用户交互数据的数据终端,移动架构的几个大模块:UI界面展示.本地数据可 ...

  2. [Android] Android 用于异步加载 ContentProvider 中的内容的机制 -- Loader 机制 (LoaderManager + CursorLoader + LoaderManager.LoaderCallbacks)

    Android 用于异步加载 ContentProvider 中的内容的机制 -- Loader 机制 (LoaderManager + CursorLoader + LoaderManager.Lo ...

  3. Android 图片异步加载的体会,SoftReference已经不再适用

      在网络上搜索Android图片异步加载的相关文章,目前大部分提到的解决方案,都是采用Map<String, SoftReference<Drawable>>  这样软引用的 ...

  4. Android图片异步加载之Android-Universal-Image-Loader

    将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...

  5. Android图片异步加载之Android-Universal-Image-Loader(转)

    今天要介绍的是Github上一个使用非常广泛的图片异步加载库Android-Universal-Image-Loader,该项目的功能十分强大,可以说是我见过的目前功能最全.性能最优的图片异步加载解决 ...

  6. android 网络异步加载数据进度条

    ProgressDialog progressDialog = null; public static final int MESSAGETYPE = 0; private void execute( ...

  7. Android 之异步加载LoaderManager

    LoaderManager: Loader出现的背景: Activity是我们的前端页面展现,数据库是我们的数据持久化地址,那么正常的逻辑就是在展示页面的渲染页面的阶段进行数据库查询.拿到数据以后才展 ...

  8. Android GridView异步加载图片和加载大量图片时出现Out Of Memory问题

    我们在使用GridView或者ListView时,通常会遇到两个棘手的问题: 1.每个Item获取的数据所用的时间太长会导致程序长时间黑屏,更甚会导致程序ANR,也就是Application No R ...

  9. android listview 异步加载图片并防止错位

    网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertVie ...

随机推荐

  1. Gym - 100971J ——DFS

    Statements Vitaly works at the warehouse. The warehouse can be represented as a grid of n × mcells, ...

  2. Java多线程设计模式(二)

        目录(?)[-] Guarded Suspension Pattern Balking Pattern Producer-Consumer Pattern   Guarded Suspensi ...

  3. centos 7防火情配置

    查看版本 firewall-cmd --version 2 查看指定端口是否开放 firewall-cmd --query-port=端口号/tcp 3 开放指定端口(--permanent表示永久, ...

  4. sqlite初识

    最近在部署PHP网站项目的时候,发现项目并没有使用传统的三大关系型数据库,而是采用了sqlite数据库,以前的时候,也见过sqlite,但是并没有深入了解其功能和用法,好奇心驱使,决定好好研究一下sq ...

  5. Gamma Correction of OIIO

    \apiitem{"oiio:ColorSpace" : string}   The name of the color space of the color channels. ...

  6. RabbitMq初探——Hello World

    HelloWorld 前言 这里我们弱化broker内部构造.将整体分为三部分. P:producer.生产者. C:Consumer.消费者. queue:队列. 后面的代码都依赖于 the php ...

  7. 关于C# 向TIM或者QQ自动发送中文消息【微信也是可用的】 附测试GIF中微信可用的 全新修订

    在上一篇文章的代码 对于微信已失效 重新更新一边 效果图: 源代码 using System; using System.Runtime.InteropServices; using System.T ...

  8. 爬虫开发10.scrapy框架之日志等级和请求传参

    今日概要 日志等级 请求传参 今日详情 一.Scrapy的日志等级 - 在使用scrapy crawl spiderFileName运行程序时,在终端里打印输出的就是scrapy的日志信息. - 日志 ...

  9. js计算机样式window.getComputedStyle(ele,null)与

    一.getComputedStyle兼容IE8以上,范户籍的计算样式的值都是绝对值,没有相对单位(如:width:10em; 它打印出来是160px) window.getComputedStyle( ...

  10. acedSSGet使用自定义提示字符:$模式

          ads_name ss; struct resbuf *pRbList=NULL; pRbList=acutBuildList(RTDXF0,_T("lwpolyline,ins ...