之前做的程序一直存在很多问题,因为需要加载的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介绍
从其中学到了很多新的知识点,非常的感谢!