1

我正在尝试为我的 android 应用程序创建一个列表视图,最后有一个页脚按钮。我正在尝试从我的数据库中读取元素,每次按下页脚按钮时使用 limit 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();
    }

}

谢谢你。

4

2 回答 2

0

问题解决了,我每次调用异步时都应该创建一个新的可运行对象

private 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();
    }

}
于 2012-07-20T10:07:38.787 回答
0

您不能在 doInBackground 中使用 ListView,因为它是不同的线程(不是 UI 线程)。你想在 UI 线程中做的所有事情(例如将适配器设置为 listview)都必须在 onPostExecute 中完成。请在此处阅读有关 AsyncTasks 的信息。

于 2012-07-20T09:13:23.380 回答