Cómo administrar adaptadores personalizados onPause, onResume of Activity en Android

Tengo un adaptador usado para exhibir mensajes en la visión de la lista iguales mensajes en la aplicación de la charla. Puedo mostrar el contenido perfectamente una vez que la actividad se crea, pero cuando vuelvo y creo la actividad otra vez, el adaptador no trabaja como de costumbre.

Lo que encontré en la depuración es la siguiente:

  • Función recibe () se llama cuando se recibe el mensaje y actualizar el registro, como he mencionado anteriormente no hay ningún problema para mostrar los datos en la vista de lista una vez que la actividad se crea, pero una vez que volver y relauch la actividad no soy capaz de Mostrar los mensajes recibidos.

¿Hay algo que me falta en onResume () onPause o onStart () método con respecto al adaptador personalizado, como el registro o la decalificación del adaptador personalizado de nuevo? Gracias por la ayuda.

A continuación se muestra el código de mi clase de actividad que utiliza un adaptador personalizado para mostrar los mensajes enviados y recibidos:

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

Aquí está mi adaptador de encargo (no hay problema en el adaptador de encargo pero agregando para hacer las cosas claras):

 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; } } 

Ps: No estoy almacenando ningún mensaje en sqlite ya que no quiero restaurar mensajes por ahora, pero quiero que se muestren nuevos mensajes por lo menos onresume de activty. Puedo mostrar los mensajes enviados después de presionar enviar botón pero no recibió mensajes que funciona bien para la primera vez que se crea la actividad.

EDIT: Hice más depuración, resulta que el problema no está en la actividad de reanudar, si no uso receive () función por primera vez, y reanudar la actividad después de volver, entonces recibe () funcionará, es decir, la función dentro recibe ): getListView().setSelection(messagex.size()-1); Funciona una sola vez. Ya sea la primera vez en la recepción de mensajes o la próxima vez si y sólo si no se llama la primera vez en la actividad.

Creo que el problema reside cuando se intenta reanudar la actividad, todavía está ejecutando el mHandler anterior en ejecución y por lo tanto su instancia de mensaje no se destruye y cuando se reanuda su actividad que crea un problema. Asegúrese de que su mhandler destruye toda instancia de objetos cuando se llama unstop.

No hay ningún lugar en el código donde guarde su messagex ArrayList. Cuando abandones tu actividad golpeando hacia atrás, tu matriz se distroye (Garbage Collection se encarga de ello).

Cuando messagex su actividad, su messagex ArrayList se crea de nuevo, es una variable nueva.

De hecho, no estás relanzando tu actividad, estás creando una nueva instancia.

EDITAR:

Nunca he trabajado con los objetos XMPPConnection antes, pero algo que vale la pena probar es el siguiente:
Cuando se enlaza con el servicio, está llamando a connection2.getChatManager().addChatListener y también arg0.addMessageListener pero al desvincular no está llamando a ningún método removeXXX . Podría ser que ya que no está eliminando a sus oyentes, todo el objeto XMPPConnection todavía tiene referencias a los oyentes que viven en una actividad muerta, y no están siendo recogidos basura.

En el código mencionado anteriormente, nunca ha actualizado ArrayList en su clase de adaptador personalizado después de reanudar la actividad o el mensaje de servicio obtener.

Solución:

Cambie su constructor de adaptador personalizado como, public ChattingAdapter(Context context) y cree un método como se menciona a continuación

 public void updateMessage(ArrayList<ChatMessage> messages) { this.mMessages.clear(); this.mMessages = messages; notifyDataSetChanged(); } 

Y también en la clase adaptadora personalizada inicializar el mMessages como new ArrayList<ChatMessage>(); En la declaración sí mismo de otra manera usted conseguirá la excepción del puntero nulo.

Y en su Activador hotListener, el método addNewMessage (ChatMessage m) debe cambiar como se menciona a continuación

 void addNewMessage(ChatMessage m) { System.out.println("1"); messagex.add(m); System.out.println("2"); adaptex.updateMessage(messagex); //adaptex.notifyDataSetChanged(); System.out.println("3"); getListView().setSelection(messagex.size()-1); } 
  • Aplicar como listview
  • Reproducir vídeo en la vista de lista de Android
  • Cómo implementar correctamente un adaptador para un ListView
  • Detenga ViewPagers dentro de ListView de restablecer
  • Fragmento Butterknife Inyectar las vistas no funciona?
  • CursorAdapter clasificación dinámica
  • Onfling y OnTouch no trabajan juntos
  • ¿Cómo puedo agregar filas a un listview de forma asíncrona?
  • Una fila a fill_parent ListView height
  • Mostrar / ocultar la vista de lista
  • Cómo mostrar un botón de imagen sólo en ciertas filas
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.