我正在尝试为我的Android应用程序制作一个列表视图,最后用一个页脚按钮。 我试图从我的数据库中读取元素,使用限制sql命令将它们放入列表每次按下页脚按钮然后我想从我的数据库等加载下一个元素。
代码正常工作,直到我按下异步调用按钮,然后我得到一个异常。
这是我的班级:
public class UIHistoryListActivity extends ListActivity {
ProgressDialog pDialog;
EfficientAdapter adap;
Databasehandler db = new Databasehandler(this);
List<Message> messages;
ArrayList<Message> menuItems = new ArrayList<Message>();
int current_page = 0;
int index = 0;
int limit = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
android.text.format.DateFormat.format("yyyy-MM-dd hh:mm:ss",
new java.util.Date());
db.addMessage(new Message("6983583727", "Hi Lakis", 1,
(String) android.text.format.DateFormat.format(
"yyyy-MM-dd hh:mm:ss", new java.util.Date())));
db.addMessage(new Message("1234567789", "Hi Takis", 1,
(String) android.text.format.DateFormat.format(
"yyyy-MM-dd hh:mm:ss", new java.util.Date())));
db.addMessage(new Message("1234344789", "Hi Makis", 1,
(String) android.text.format.DateFormat.format(
"yyyy-MM-dd hh:mm:ss", new java.util.Date())));
db.addMessage(new Message("1234553229", "Hi Sakis", 0,
(String) android.text.format.DateFormat.format(
"yyyy-MM-dd hh:mm:ss", new java.util.Date())));
db.addMessage(new Message("1234567781", "Hi Akis", 1,
(String) android.text.format.DateFormat.format(
"yyyy-MM-dd hh:mm:ss", new java.util.Date())));
db.addMessage(new Message("6983583727", "Hi Qakis", 1,
(String) android.text.format.DateFormat.format(
"yyyy-MM-dd hh:mm:ss", new java.util.Date())));
db.addMessage(new Message("1234567789", "Hi Wakis", 1,
(String) android.text.format.DateFormat.format(
"yyyy-MM-dd hh:mm:ss", new java.util.Date())));
db.addMessage(new Message("1234344789", "Hi Eakis", 1,
(String) android.text.format.DateFormat.format(
"yyyy-MM-dd hh:mm:ss", new java.util.Date())));
db.addMessage(new Message("1234553229", "Hi Yakis", 0,
(String) android.text.format.DateFormat.format(
"yyyy-MM-dd hh:mm:ss", new java.util.Date())));
db.addMessage(new Message("1234567781", "Hi Ukis", 1,
(String) android.text.format.DateFormat.format(
"yyyy-MM-dd hh:mm:ss", new java.util.Date())));
//putting the first 5 messages of my db on the list
messages = db.getMessages(0, 5);
index += 5;
limit = limit + 5;
for (Message mg : messages) {
menuItems.add(new Message(mg.getID(), mg.getPhoneNumber(), mg
.getBody(), mg.getStatus(), mg.getDate()));
}
/*
* menuItems.add(new Message(1, "1234553229", "Hi Sakis", 0, "lala"));
* menuItems.add(new Message(1, "1234553229", "Hi Lakis", 0, "lala"));
* menuItems.add(new Message(1, "1234553229", "Hi Takis", 0, "lala"));
* menuItems.add(new Message(1, "1234553229", "Hi Aakis", 0, "lala"));
* menuItems.add(new Message(1, "1234553229", "Hi Qakis", 1, "lala"));
* menuItems.add(new Message(1, "1234553229", "Hi Wakis", 1, "lala"));
* menuItems.add(new Message(1, "1234553229", "Hi Eakis", 0, "lala"));
* menuItems.add(new Message(1, "1234553229", "Hi Rakis", 0, "lala"));
* menuItems.add(new Message(1, "1234553229", "Hi Yakis", 1, "lala"));
* menuItems.add(new Message(1, "1234553229", "Hi Uakis", 0, "lala"));
* menuItems.add(new Message(1, "1234553229", "Hi Oakis", 0, "lala"));
*/
adap = new EfficientAdapter(this, menuItems);
ListView lv = getListView();
// Creating a button - Load More
Button btnLoadMore = new Button(this);
btnLoadMore.setText("Load More");
btnLoadMore.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// Starting a new async task
// CharSequence text = "Ok dude you pressed me ";
// Toast toast = Toast.makeText(getApplicationContext(), text,
// Toast.LENGTH_SHORT);
// toast.show();
new loadMoreListView().execute();
}
});
// Adding button to listview at footer
lv.addFooterView(btnLoadMore);
setListAdapter(adap);
// adap = new ListViewAdapter(this, messages);
lv.setAdapter(adap);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
Toast.makeText(this, "Click-" + String.valueOf(position),
Toast.LENGTH_SHORT).show();
}
/**
* Async Task that send a request to url Gets new list view data Appends to
* list view
* */
private class loadMoreListView extends AsyncTask<List<Message>, Void, Void> {
@Override
protected void onPreExecute() {
// Showing progress dialog before sending http request
pDialog = new ProgressDialog(UIHistoryListActivity.this);
pDialog.setMessage("Please wait..");
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected Void doInBackground(List<Message>... params) {
// TODO Auto-generated method stub
// UIHistoryListActivity.this
// ListView lv = getListView();
// for (Message mg : messages) {
// menuItems.add(new Message(mg.getID(), mg.getPhoneNumber(), mg
// .getBody(), mg.getStatus(), mg.getDate()));
//
// }
// setListAdapter(adap);
// adap = new ListViewAdapter(this, messages);
// lv.setAdapter(adap);
current_page = current_page + 1;
//putting the next 5 messages of my db on the list
messages = db.getMessages(index, limit);
index += limit;
limit = index + 5;
ListView lv = getListView();
for (Message mg : messages) {
menuItems.add(new Message(mg.getID(), mg.getPhoneNumber(), mg
.getBody(), mg.getStatus(), mg.getDate()));
}
//setListAdapter(adap); edw petouse exception
// adap = new ListViewAdapter(this, messages);
adap = new EfficientAdapter(UIHistoryListActivity.this, menuItems);
lv.setAdapter(adap);
// Setting new scroll position
int currentPosition = lv.getFirstVisiblePosition();
lv.setSelectionFromTop(currentPosition + 1, 0);
return null;
}
protected void onPostExecute(Void unused) {
// closing progress dialog
pDialog.dismiss();
}
}
public static class EfficientAdapter extends ArrayAdapter<Message>
implements Filterable {
private LayoutInflater mInflater;
// private Bitmap mIcon1;
private final Context context;
private final ArrayList<Message> values;
public EfficientAdapter(Context context, ArrayList<Message> values) {
// Cache the LayoutInflate to avoid asking for a new one each time.
super(context, R.layout.mycontent, values);
mInflater = LayoutInflater.from(context);
this.context = context;
this.values = values;
}
/**
* Make a view to hold each row.
*
* @see android.widget.ListAdapter#getView1(int, android.view.View,
* android.view.ViewGroup)
*/
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid
// unneccessary calls
// to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is
// no need
// to reinflate it. We only inflate a new View when the convertView
// supplied
// by ListView is null.
if (convertView == null) {
convertView = mInflater.inflate(R.layout.mycontent, null);
holder = new ViewHolder();
holder.body = (TextView) convertView.findViewById(R.id.body);
holder.date = (TextView) convertView.findViewById(R.id.date);
holder.from = (TextView) convertView.findViewById(R.id.from);
holder.status = (TextView) convertView
.findViewById(R.id.status);
convertView.setTag(holder);
}
else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
convertView.setOnClickListener(new OnClickListener() {
private int pos = position;
// private String toId =
// Integer.toString(values.get(position).getId());
@Override
public void onClick(View v) {
Toast.makeText(context, "Click-" + pos, Toast.LENGTH_SHORT)
.show();
}
});
// holder.textLine.setText(TitleString[position] +
// String.valueOf(position));
holder.body.setText(getItem(position).getBody());
holder.date.setText(getItem(position).getDate());
holder.from.setText(getItem(position).getPhoneNumber());
holder.status
.setText(String.valueOf(getItem(position).getStatus()));
return convertView;
}
static class ViewHolder {
TextView from;
TextView date;
TextView body;
TextView status;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return values.size();
}
@Override
public Message getItem(int position) {
// TODO Auto-generated method stub
return values.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public Filter getFilter() {
// TODO Auto-generated method stub
return null;
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
db.close();
}
}
谢谢。
答案 0 :(得分:0)
您不能在doInBackground中使用ListView,因为它是不同的线程(不是UI线程)。您想要在UI线程中执行的所有操作(例如将适配器设置为listview)必须在onPostExecute中完成。 请阅读有关AsyncTasks的here。
答案 1 :(得分:0)
问题解决了 每次调用异步
时,我都应该创建一个新的runnableprivate class loadMoreListView extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
pDialog = new ProgressDialog(UIHistoryListActivity.this);
pDialog.setMessage("Please wait..");
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected Void doInBackground(Void... unused) {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
public void run() {
List<Message> messages;
current_page = current_page + 1;
messages = db.getMessages(index, limit);
index += limit;
limit = index + 5;
ListView lv = getListView();
for (Message mg : messages) {
menuItems.add(new Message(mg.getID(), mg
.getPhoneNumber(), mg.getBody(),
mg.getStatus(), mg.getDate()));
}
// Setting new scroll position
int currentPosition = lv.getFirstVisiblePosition();
adap = new EfficientAdapter(UIHistoryListActivity.this,
menuItems);
lv.setAdapter(adap);
lv.setSelectionFromTop(currentPosition + 1, 0);
}
});
return null;
}
protected void onPostExecute(Void unused) {
// closing progress dialog
pDialog.dismiss();
}
}