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 messageCenters
103      */
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     @Override
113     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 Administrator
132      *
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             @Override
155             public void onClick(View arg0) {
156                 MessageCenterListActivity.this.finish();
157             }
158         });
159     }
160 
161     /**
162      * 
163      * @author Administrator
164      *
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         @Override
193         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         @Override
218         protected void onPostExecute(List<MessageCenter> result) {
219             loadDataForNet(result);
220             super.onPostExecute(result);
221         }
222         
223         /**
224          * 加载网络数据
225          * @param result
226          */
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             else
249             {
250                 Log.i(TAG, "[Method:loadDataForNetFirst] messageCenterList is null");
251             }
252         }        
253     }
254     
255 }

 

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

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

Android AsyncTask异步加载WebAPI,布布扣,bubuko.com

Android AsyncTask异步加载WebAPI

上一篇:CSS3 Loading(加载)动画效果


下一篇:Unity3d:使用uWebKit插件嵌入网页,网页中的flv视频无法播放