首页 > 代码库 > Android AsyncTask异步加载WebAPI

Android AsyncTask异步加载WebAPI

之前做的程序一直存在很多问题,因为需要加载的Activity需要从网络加载数据。并没有完全正确的使用异步的方法去加载!

之前用的虽然是AsyncTask,但是在加载完成的时候还是并没有使用AsyncTask内置的方法去处理。而已傻傻的在OnCreate中处理。结果还是要等待AsyncTask加载完成后,等待OnCreate执行完成后,才load到Activity。这样子给人的第一感觉就是卡机了一样!

果断重新再写,这次的代码真是大换血。首先还是选择把带分页ListView进行封装了一下。

  1 import com.sf.campus.R;  2   3 import android.app.Activity;  4 import android.os.Handler;  5 import android.util.Log;  6 import android.view.View;  7 import android.view.View.OnClickListener;  8 import android.widget.BaseAdapter;  9 import android.widget.Button; 10 import android.widget.ListAdapter; 11 import android.widget.ListView; 12 import android.widget.Toast; 13  14 /** 15  * 模版化的ListView 16  * @author Administrator 17  * 18  */ 19 public class ListViewPageTemplate { 20      21     private View loadMoreView; //用来显示加载更多的一个视图  22     private Button loadMoreButton; //视图中的按钮 23     private int datasize; // 记录已有数据条数 24     private int pageindex = 1;// 页面的位置,若没有传入则默认为1 25     private int pagesize = 3; //每页显示的数量 26      27     private Activity  activity;//当前的Activity 28     private ListView myList;//当前page使用的List 29     private ListAdapter myAdapter = null;//用来传输数据 30     private Handler handler = new Handler(); 31      32     private OnExcuteListener onExcuteListener; 33     public interface OnExcuteListener{ 34         void excute(); 35     } 36     private static final String TAG="Informacation"; 37              38     /** 39      * 构造函数 40      * @param activity 上下文的Activity 41      * @param myList 用来显示的ListView 42      */ 43     public ListViewPageTemplate(Activity activity, ListView myList) { 44         super(); 45         this.activity = activity; 46         this.myList = myList; 47         init(); 48     } 49      50     private void init(){     51         Log.i(TAG, "[page] begin init"); 52         loadMoreView = activity.getLayoutInflater().inflate(R.layout.loadmore, null); 53         loadMoreButton = (Button) loadMoreView.findViewById(R.id.loadMoreButton); 54         myList.addFooterView(loadMoreView); //设置列表底部视图 55         initLoadMore(); 56         Log.i(TAG, "[page] end init"); 57     } 58      59     /** 60      * 点击加载更多 61      */ 62     private void initLoadMore(){    63         loadMoreButton.setOnClickListener(new OnClickListener() {         64             @Override 65             public void onClick(View arg0) { 66                 pageindex++; 67                 loadMoreButton.setText("正在加载中..."); 68                 handler.postDelayed(new Runnable() {    69                      public void run() {   70                          loadMoreData();   71                          ((BaseAdapter) myAdapter).notifyDataSetChanged();   72                          loadMoreButton.setText("查看更多...");  //恢复按钮文字   73                      }   74                  },3000);  75             } 76         }); 77     } 78      79     /** 80      * 加载数据,更新ListView 81      */ 82     private void loadMoreData(){ 83         int count = myAdapter.getCount();       84         if(count+pagesize < datasize){ 85             if(onExcuteListener!= null) 86                 onExcuteListener.excute(); 87             else{ 88                 Log.i(TAG, "[page] onExcuteListener is null"); 89             } 90         }else{   91             if(onExcuteListener!= null) 92                 onExcuteListener.excute();//已经加载完成 93             else{ 94                 Log.i(TAG, "[page] onExcuteListener is null"); 95             } 96             ((BaseAdapter) myAdapter).notifyDataSetChanged(); 97             myList.removeFooterView(loadMoreView);   98             alert("已加载完成!");   99             100         }  101     }102     103     public void alert (String msg)104     {105         Toast.makeText(activity.getApplicationContext(), msg, Toast.LENGTH_LONG).show();106     }107 108     public int getDatasize() {109         return datasize;110     }111 112     public void setDatasize(int datasize) {113         this.datasize = datasize;114     }115 116     public int getPageindex() {117         return pageindex;118     }119 120     public void setPageindex(int pageindex) {121         this.pageindex = pageindex;122     }123 124     public int getPagesize() {125         return pagesize;126     }127 128     public void setPagesize(int pagesize) {129         this.pagesize = pagesize;130     }131     132     public ListView getMyList() {133         return myList;134     }135 136     public void setMyList(ListView myList) {137         this.myList = myList;138     }139 140     public ListAdapter getMyAdapter() {141         return myAdapter;142     }143 144     public void setMyAdapter(ListAdapter myAdapter) {145         this.myAdapter = myAdapter;146     }147 148     public OnExcuteListener getOnExcuteListener() {149         return onExcuteListener;150     }151 152     public void setOnExcuteListener(OnExcuteListener onExcuteListener) {153         this.onExcuteListener = onExcuteListener;154     }155 156 }

 

我这里封装的ListView主要还有一个加载点击后要触发的事件,发现在类里面写个接口挺好的。

整个ListViewPageTemplate类,主要有ListView和Adapter,还有pagesize,pageindex,datasize等一些判断分页的参数。

接下来就是使用了,首先初始化一下。

1 private ListViewPageTemplate listViewTemplate = null;2 private ListView messageCenterList;3 private List<MessageCenter> messageCenters;//ListView显示的数据4 messageCenterList =  (ListView) this.findViewById(R.id.listViewMessageCenter);5 messageCenters = new ArrayList<MessageCenter>();6 listViewTemplate = new ListViewPageTemplate(MessageCenterListActivity.this , messageCenterList);

 

然后当前Activity需要实现ListViewPageTemplate.OnExcuteListener接口。

 1 listViewTemplate.setOnExcuteListener(this); 2 @Override 3 public void excute() { 4     MessageCenterTask task = new MessageCenterTask(); 5     try { 6         Log.i("Informacation", "begin excute"); 7         /** 8          * 异步处理的类 9          */    10         task.execute();11         Log.i("Informacation", "end excute");12     }13     catch (Exception e)14     {15         task.cancel(true);16     }17 }

 

MessageCenterTask一开始是写在别的类里面,后来发现他要用到ListView用到,ListView中的数据和Adapter。然后继承AsyncTask的类实现的doInBackground只能被调用一次,发现又写不下去了于是索性把MessageCenterTask写到Activity类的内部作为内部类存在。发现可用!哈哈!

  1 import java.util.ArrayList;  2 import java.util.List;  3   4 import org.apache.http.NameValuePair;  5 import org.apache.http.message.BasicNameValuePair;  6   7 import com.sf.campus.adapter.MessageCenterAdapter;  8 import com.sf.campus.dao.MessageCenterDAO;  9 import com.sf.campus.models.MessageCenter; 10 import com.sf.campus.models.MessageCenterJsonBean; 11 import com.sf.campus.utils.ConstantService; 12 import com.sf.campus.utils.JSONHttpClient; 13 import com.sf.campus.utils.ListViewPageTemplate; 14 import com.sf.campus.utils.WifiService; 15  16 import android.app.Activity; 17 import android.os.AsyncTask; 18 import android.os.Bundle; 19  20 import android.util.Log; 21 import android.view.LayoutInflater; 22 import android.view.View; 23 import android.view.View.OnClickListener; 24  25 import android.widget.BaseAdapter; 26 import android.widget.LinearLayout; 27 import android.widget.ListAdapter; 28 import android.widget.ListView; 29 import android.widget.TextView; 30 import android.widget.Toast; 31  32 public class MessageCenterListActivity extends Activity  implements ListViewPageTemplate.OnExcuteListener{ 33  34     private ListView messageCenterList; 35     private ListAdapter adapter; 36  37     private ListViewPageTemplate listViewTemplate = null; 38  39     private List<MessageCenter> messageCenters;//ListView显示的数据 40     private boolean isFirstPage = true; 41  42     private static final String TAG="Informacation"; 43      44     @Override 45     protected void onCreate(Bundle savedInstanceState) { 46         Log.i(TAG, "onCreate"); 47         super.onCreate(savedInstanceState); 48         setContentView(R.layout.messagecenter_list); 49         messageCenterList =  (ListView) this.findViewById(R.id.listViewMessageCenter); 50         messageCenters = new ArrayList<MessageCenter>(); 51         /** 52          * 与界面相关包含ListView实现一些分页功能 53          */ 54         listViewTemplate = new ListViewPageTemplate(MessageCenterListActivity.this , messageCenterList); 55          56         Log.i(TAG, "对象已经初始化完成!"); 57  58     } 59      60     @Override 61     protected void onStart() { 62         super.onStart(); 63         if (new WifiService(MessageCenterListActivity.this).isNetworkConnected() == true) { 64             Log.e("Informacation", "网络加载"); 65             excute(); 66         } else { 67             Log.e("Informacation", "本地加载"); 68             // 如果没有网络则直接加载本地数据 69             loadDataForLocal(); 70         }     71         listViewTemplate.setOnExcuteListener(this); 72         setTitle(); 73         addTitleBack(); 74     } 75  76     public void alert (String msg) 77     { 78         Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show(); 79     } 80      81      82     /** 83      * 加载本地数据 84      */ 85     public void loadDataForLocal() { 86         MessageCenterDAO dao = new MessageCenterDAO(getApplicationContext()); 87         List<MessageCenter> mcs = dao.getScrollData(0, 8); 88          89         if( messageCenters != null ){ 90             listViewTemplate.setDatasize(Integer.valueOf(mcs.get(0).getDatasize())); 91             adapter = new MessageCenterAdapter(LayoutInflater.from(MessageCenterListActivity.this), mcs);  92             listViewTemplate.setMyAdapter(adapter); 93             listViewTemplate.getMyList().setAdapter(listViewTemplate.getMyAdapter()); 94         }else{ 95             Log.i(TAG, "[Method:loadDataForLocal] messageCenterList is null"); 96         } 97     } 98      99     100     /**101      * 保存到本地102      * @param messageCenters103      */104     public void save(List<MessageCenter> messageCenters){105         MessageCenterDAO dao = new MessageCenterDAO(getApplicationContext());106         dao.deleteAll();107         for(MessageCenter mc : messageCenters){108             dao.save(mc);109         }110     }111 112     @Override113     public void excute() {114         MessageCenterTask task = new MessageCenterTask();115         try {116             Log.i("Informacation", "begin excute");117             /**118              * 提供常用CURD及数据获取的类119              */    120             task.execute();121             Log.i("Informacation", "end excute");122         }123         catch (Exception e)124         {125             task.cancel(true);126         }127     }128     129     /**130      * adapter的一些字段131      * @author Administrator132      *133      */134     public static class MessageCenterRowHolder {135         public TextView messageCenterId, messageCenterTitle;136         public MessageCenter messageCenter;137     }138     139     /**140      * 设置标题141      */142     private void setTitle(){143         TextView tv = (TextView) this.findViewById(R.id.title_text);144         tv.setText("消息中心");145     }146     147     /**148      * 返回事件149      */150     private void addTitleBack(){151         LinearLayout layout= (LinearLayout) this.findViewById(R.id.title_back);152         layout.setOnClickListener(new OnClickListener() {153             154             @Override155             public void onClick(View arg0) {156                 MessageCenterListActivity.this.finish();157             }158         });159     }160 161     /**162      * 163      * @author Administrator164      *165      */166     class MessageCenterTask  extends AsyncTask<String, String, List<MessageCenter>>{167     168         String URL= ConstantService.HEAD + ConstantService.SCHOOL + ConstantService.MESSAGECENTER_SERVICE_URL;      169          170         private List<NameValuePair> createNameValuePairs(){171             Log.i(TAG,  "userId=" + String.valueOf( ConstantService.userID )  + 172                         "pageIndex="+ String.valueOf( listViewTemplate.getPageindex()) +173                         "pageSize" + String.valueOf(listViewTemplate.getPagesize()));174             List<NameValuePair> list = new ArrayList<NameValuePair>();175             NameValuePair p1 = new BasicNameValuePair("userId", String.valueOf( ConstantService.userID ) );176             NameValuePair p2 = new BasicNameValuePair("pageIndex", String.valueOf( listViewTemplate.getPageindex() ) );177             NameValuePair p3 = new BasicNameValuePair("pageSize" , String.valueOf(listViewTemplate.getPagesize()));178             NameValuePair p4 = new BasicNameValuePair("format" , "json");179             list.add(p1);180             list.add(p2);181             list.add(p3);182             list.add(p4);183             return list;184         }185 186         /**  187          * 这里的Integer参数对应AsyncTask中的第一个参数   188          * 这里的String返回值对应AsyncTask的第三个参数  189          * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改  190          * 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作  191          */  192         @Override193         protected List<MessageCenter> doInBackground(String... arg0) {194             Log.i(TAG, "Task Start");195             List<NameValuePair> pairs =  createNameValuePairs();196             List<MessageCenter> mcs= new ArrayList<MessageCenter>();197             JSONHttpClient client= new JSONHttpClient();     198             MessageCenterJsonBean result= client.Get(URL, pairs, MessageCenterJsonBean.class );    199             //存储页面的大小200             listViewTemplate.setDatasize(result.getTotal()); 201             for(int i=0; i<result.getRows().size(); i++){202                 MessageCenter messageCenter = new MessageCenter();203                 messageCenter.setID(result.getRows().get(i).getID());204                 messageCenter.setTitle(result.getRows().get(i).getTitle());205                 messageCenter.setContent(result.getRows().get(i).getContent());206                 mcs.add(messageCenter);207             }208             Log.i(TAG, "Task End");209             return  mcs;210 211         }212         213         /**  214          * 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)  215          * 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置  216          */217         @Override218         protected void onPostExecute(List<MessageCenter> result) {219             loadDataForNet(result);220             super.onPostExecute(result);221         }222         223         /**224          * 加载网络数据225          * @param result226          */227         private void loadDataForNet(List<MessageCenter> result) {228             if(result != null)229             {230                 //若是第一页则保存到本地231                 if(isFirstPage){232                     Log.i(TAG, "第一次加载!");233                     save(result);234                     messageCenters.clear();235                     messageCenters.addAll(result);236                     adapter = new MessageCenterAdapter(LayoutInflater.from(MessageCenterListActivity.this),  messageCenters);237                     listViewTemplate.setMyAdapter(adapter);238                     listViewTemplate.getMyList().setAdapter(listViewTemplate.getMyAdapter());239                     //listViewTemplate.setMyAdapter(adapter);240                     isFirstPage = false;241                 }else{242                     Log.i(TAG, "不是第一次加载!更新!");243                     messageCenters.addAll(result);244                     ((BaseAdapter) adapter).notifyDataSetChanged();245                 }246 247             }248             else249             {250                 Log.i(TAG, "[Method:loadDataForNetFirst] messageCenterList is null");251             }252         }        253     }254     255 }

 

算是实现了,真是不容易啊!感谢DevinZhang博主的一篇文章android AsyncTask介绍

从其中学到了很多新的知识点,非常的感谢!