Question

when I execute the project it works eventually it stop

java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131361944, class android.widget.ListView) with Adapter(class com.pocketpharmacist.adapter.DrugClassesListAdapter)]

the problem it i cant used runOnUiThread bexause of the class axtend

@Override
    public void onConversationMessage(String target)
    {
        Conversation conversation = server.getConversation(target);

        if (conversation == null) {
            // In an early state it can happen that the conversation object
            // is not created yet.
            return;
        }

        MessageListAdapter adapter = deckAdapter.getItemAdapter(target);

        while(conversation.hasBufferedMessages()) {
            Message message = conversation.pollBufferedMessage();

            if (adapter != null && message != null) {
                adapter.addMessage(message);
                int status;

                switch (message.getType())
                {
                    case Message.TYPE_MISC:
                        status = Conversation.STATUS_MISC;
                        break;

                    default:
                        status = Conversation.STATUS_MESSAGE;
                        break;
                }
                conversation.setStatus(status);
            }
        }

        if (dots != null) {
            dots.invalidate();
        }
    }









for (Conversation conversation : mConversations) {
            mAdapter = deckAdapter.getItemAdapter(conversation.getName());

            if (mAdapter != null) {
                mAdapter.addBulkMessages(conversation.getBuffer());
                conversation.clearBuffer();
            }





  public class MessageListAdapter extends BaseAdapter
    {
        private final LinkedList<TextView> messages;
        private final Context context;
        private final int historySize;

        /**
         * Create a new MessageAdapter
         * 
         * @param channel
         * @param context
         */

        public MessageListAdapter(Conversation conversation, Context context)
        {
            LinkedList<TextView> messages = new LinkedList<TextView>();

            // Render channel name as first message in channel
            if (conversation.getType() != Conversation.TYPE_SERVER) {
                Message header = new Message(conversation.getName());
                header.setColor(Message.COLOR_RED);
                messages.add(header.renderTextView(context));
            }

            // Optimization - cache field lookups
            LinkedList<Message> mHistory =  conversation.getHistory();
            int mSize = mHistory.size();

            for (int i = 0; i < mSize; i++) {
                messages.add(mHistory.get(i).renderTextView(context));
            }

            // XXX: We don't want to clear the buffer, we want to add only
            //      buffered messages that are not already added (history)
            conversation.clearBuffer();

            this.messages = messages;
            this.context = context;
            historySize = conversation.getHistorySize();
        }

        /**
         * Add a message to the list
         * 
         * @param message
         */
        public void addMessage(Message message)
        {
            messages.add(message.renderTextView(context));

            if (messages.size() > historySize) {
                messages.remove(0);
            }

            notifyDataSetChanged();
        }

        /**
         * Add a list of messages to the list
         * 
         * @param messages
         */

        public void addBulkMessages(LinkedList<Message> messages)
        {
            LinkedList<TextView> mMessages = this.messages;
            Context mContext = this.context;
            int mSize = messages.size();

            for (int i = mSize - 1; i > -1; i--) {
                mMessages.add(messages.get(i).renderTextView(mContext));

                if (mMessages.size() > historySize) {
                    mMessages.remove(0);
                }
            }
            notifyDataSetChanged();
        }

        /**
         * Get number of items
         * 
         * @return
         */
        @Override
        public int getCount()
        {
            return messages.size();
        }

        /**
         * Get item at given position
         * 
         * @param position
         * @return
         */
        @Override
        public TextView getItem(int position)
        {
            return messages.get(position);
        }

        /**
         * Get id of item at given position
         * 
         * @param position
         * @return
         */
        @Override
        public long getItemId(int position)
        {
            return position;
        }

        /**
         * Get item view for the given position
         * 
         * @param position
         * @param convertView
         * @param parent
         * @return
         */
        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            return getItem(position);
        }
    }

No correct solution

OTHER TIPS

Based on the error message, the problem is likely that you are modifying the contents of your adapter within the callback "onConversationMessage." This is not likely running on the main thread and so cannot be used to update your adapter. What you could do to fix this is move your methods that deal with the adapter into a Runnable and then get the Activity context from within onConversationMessage and run on UI thread from there.

Runnable updateAdapter = new Runnable(){

    @Override
    public void run(){
        //Move all your actions updating adapter here
    }
}

Then within your onConversationMessage if you're within a fragment

getActivity().runOnUiThread(updateAdapter);

If you're in an activity you can use that as your context

ActivityName.this.runOnUiThread(updateAdapter);

You will have to change your structure slightly to make this work. For example, you're adapter will likely need to be an instance variable so that you end up updating the same adapter you're applying to the list.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top