Domanda

I have an adapter used to display messages on the list view alike messages in chat application . I am able to display the content flawlessly once the activity is created , but when I go back and create activity again , adapter don't work as usual .

What I found in debugging is follows:

  • function receives() is called when message is received and update the register , as I mentioned above there is no problem to display the data in list view once the activity is created , but once I go back and relauch the activity I am not able to display received messages .

Is there something I am missing in onResume() onPause or onStart() method with respect to custom adapter such as registering or decalring the custom adapter again? Thanks for help.

Following is the code of my activity class which uses custom adapter to display sent and received messages:

public class hotListener extends ListActivity {


    private XMPPConnection connection;
    private IBinder binder;
    private Handler mHandler = new Handler();
    private ArrayList<String> messages = new ArrayList<String>();
    ArrayList<ChatMessage> messagex= new ArrayList<ChatMessage>();;
    ChattingAdapter adaptex;

    Intent mIntent ;
    private ListView listview;
    EditText sender_message ;
    String msg;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.listener);
        //messagex.add(new ChatMessage("Hello", false));
        adaptex  = new ChattingAdapter(getApplicationContext(),messagex);
        setListAdapter(adaptex);

        Button send_button = (Button) findViewById(R.id.chat_send_message);
        sender_message = (EditText) findViewById(R.id.chat_input);
        send_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                msg = sender_message.getText().toString();
                sender_message.setText("");
                if(!(msg.length()==0)){
                    messagex.add(new ChatMessage(msg, true));
                    //addNewMessage(new ChatMessage(msg, true));
                    adaptex.notifyDataSetChanged();
                    getListView().setSelection(messagex.size()-1);
                }

            }
        });
        if(!isMyServiceRunning()){
            System.out.println("seems like service not running");
            startService(new Intent(this,xService.class));
            System.out.print(" now started ");
        }       
    }

    @Override
    protected void onStart(){
        super.onStart();
        Boolean kuch = bindService(new Intent(this,xService.class), mConnection,Context.BIND_AUTO_CREATE);
        //System.out.println(kuch);
        System.out.println("bind done");        
    }

    private void receives(XMPPConnection connection2) {
            //ChatManager chatmanager = connection.getChatManager();
            connection2.getChatManager().addChatListener(new ChatManagerListener() {

                @Override
                public void chatCreated(Chat arg0, boolean arg1) {
                    arg0.addMessageListener(new MessageListener() {

                        @Override
                        public void processMessage(Chat chat, Message message) {

                            final String from = message.getFrom();
                            final String body = message.getBody();
                            mHandler.post(new Runnable() {
                                ChatMessage kudi = new ChatMessage(body, false);

                                @Override
                                public void run() {

                                    messagex.add(kudi);
                                    adaptex.notifyDataSetChanged();
                                    getListView().setSelection(messagex.size()-1);
                                    Toast.makeText(hotListener.this,body,Toast.LENGTH_SHORT).show();                                }
                            });
                        }
                    });
                }
            });
    }

    private boolean isMyServiceRunning() {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for(RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)){
            if(xService.class.getName().equals(service.service.getClassName())){
                return true;
            }
        }
        //System.out.print("false");
        return false;
    }

    @Override
      protected void onResume() {
        bindService(new Intent(this, xService.class), mConnection, Context.BIND_AUTO_CREATE);
        super.onResume();
      }
     @Override
      protected void onPause() {
        unbindService(mConnection);
        super.onPause();
      }

     private ServiceConnection mConnection = new ServiceConnection() {

            @Override
            public void onServiceDisconnected(ComponentName name) {
                connection = null;
                service = null;
            }

            @Override
            public void onServiceConnected(ComponentName name, IBinder binder) {
                //System.out.println("binding in hot listener");
                service = ((xService.MyBinder)binder).getService();
                connection = service.getConnection();
                receives(connection);
                Log.wtf("Service","connected");
            }
        };

        void addNewMessage(ChatMessage m)
        {
            System.out.println("1");
            messagex.add(m);
            System.out.println("2");
            adaptex.notifyDataSetChanged();
            System.out.println("3");
            getListView().setSelection(messagex.size()-1);
        }
}

Here is my custom adapter (there is no problem in custom adapter but adding to make things clear) :

public class ChattingAdapter extends BaseAdapter{
    private Context mContext;
    private ArrayList<ChatMessage> mMessages;


    public ChattingAdapter(Context context, ArrayList<ChatMessage> messages) {
        super();
        this.mContext = context;
        this.mMessages = messages;
    }
    @Override
    public int getCount() {
        return mMessages.size();
    }
    @Override
    public Object getItem(int position) {       
        return mMessages.get(position);
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ChatMessage message = (ChatMessage) this.getItem(position);

        ViewHolder holder; 
        if(convertView == null)
        {
            holder = new ViewHolder();
            convertView = LayoutInflater.from(mContext).inflate(R.layout.listitem, parent, false);
            holder.message = (TextView) convertView.findViewById(R.id.text1);
            convertView.setTag(holder);
        }
        else
            holder = (ViewHolder) convertView.getTag();

        holder.message.setText(message.getMessage());
        LayoutParams lp = (LayoutParams) holder.message.getLayoutParams();      

        //Check whether message is mine to show green background and align to right

        if(message.isMine())

        {           holder.message.setBackgroundResource(R.drawable.msgbox_new_selected_go_up);         

                lp.gravity = Gravity.RIGHT;     
        }
        //If not mine then it is from sender to show orange background and align to left

        else        
        {
            holder.message.setBackgroundResource(R.drawable.msgbox_other_go_up);

            lp.gravity = Gravity.LEFT;

        }
            holder.message.setLayoutParams(lp);
            //holder.message.setTextColor(R.color.textColor);   

        return convertView;
    }
    private static class ViewHolder
    {
        TextView message;
    }

    @Override
    public long getItemId(int position) {
        //Unimplemented, because we aren't using Sqlite.
        return position;
    }

}

p.s: I am not storing any messages in sqlite as I dont want to restore messages for now, but I want new messages to be displayed at least onresume of activty. I can display sent messages after pressing send button but no received messages which works fine for the first time activity is created.

EDIT: I did more debugging , it turns out problem is not in resume activity , if I dont use receives() function for first time , and resume activity after going back , then receives() will work , that means , function inside receives() : getListView().setSelection(messagex.size()-1); works only once . Either first time on receiving message or next time if and only if its not called first time on activity .

È stato utile?

Soluzione

I think problem lies when you try to resume activity , you are still running the previous mHandler running and thus your instance of message is not destroyed and when you resume your activity it creates a problem . Make sure your mhandler destroys all instance of objects when unstop is called.

Altri suggerimenti

There's no place in your code where you save your messagex ArrayList. When you quit your activity by hitting back, your array get's distroyed (Garbage Collection takes care of it).

When you relaunch your activity your messagex ArrayList is created again, it's a brand new variable.

In fact, you're not relaunching your activity, you're creating a new instance.

EDIT:

I've never worked with the XMPPConnection objects before, but something else worth trying is the following:
When binding to the service, you're calling connection2.getChatManager().addChatListener and also arg0.addMessageListener but when unbinding you're not calling any removeXXX methods. I could be that since you're not removing your listeners, the whole XMPPConnection object still have references to the listeners that live in a dead Activity, and they are not being garbage collected.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top