首页 > 代码库 > 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介绍
从其中学到了很多新的知识点,非常的感谢!
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。