Сообщение обработчика Android и ListView - PullRequest
9 голосов
/ 06 ноября 2010

Вот моя ошибка:

*** Uncaught remote exception!  (Exceptions are not yet supported across processes.)
android.util.AndroidRuntimeException: { what=1008 when=368280372 } This message is already in use.
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:171)
at android.os.Handler.sendMessageAtTime(Handler.java:457)
at android.os.Handler.sendMessageDelayed(Handler.java:430)
at android.os.Handler.sendMessage(Handler.java:367)
at android.view.ViewRoot.dispatchAppVisibility(ViewRoot.java:2748)

Я пытаюсь создать представление списка, заполненное пользовательскими элементами списка, каждый элемент списка имеет несколько представлений, и к каждому представлению прикреплен прослушиватель onclick.Когда этот onClickListener нажат, он отправляет сообщение обработчику с аргументами what и arg1.Нажатие одного из моих элементов вызывает желание начать новую деятельность.Нажатие другой показывает тост.Когда они нажимаются в комбинации, я получаю ошибку выше.А именно, щелкнув по тексту, чтобы запустить намерение, (затем нажмите назад), затем щелкнув по изображению, чтобы показать тост, затем, когда вы щелкнете текст, чтобы запустить намерение, я получу ФК.

И вот кодниже я постарался удалить как можно больше ошибок, чтобы добраться до сути ошибки:

Если вы хотите перейти к важному взгляду на onClickListener в ConversationAdapter.class и на то, как они взаимодействуют с StartPage.class

Манифест Android:

<?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.handler.test"
    android:versionCode="1"
    android:versionName="1.0">
      <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".StartPage"
              android:label="@string/app_name">
            <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    <activity
        android:name=".DetailsPage"
        android:label="DetailsPage"
        >
    </activity> 
    </application>
    <uses-sdk android:minSdkVersion="3" />
</manifest>

StartPage.class:

package com.handler.test;

import java.util.ArrayList;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

public class StartPage extends ListActivity {

private ArrayList<Conversation> mConversations = null;
private ConversationAdapter mAdapter;
private Context mContext;
private ProgressDialog mProgressDialog;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    mContext = this;

    mConversations = new ArrayList<Conversation>();
    this.mAdapter = new ConversationAdapter(mContext, R.layout.inbox_row, mConversations, mHandler);
    setListAdapter(this.mAdapter);

    new Thread(new Runnable() {
        @Override
        public void run() {
            getConversations();
        }
    }).start();

    mProgressDialog = ProgressDialog.show(StartPage.this, "Please wait...", "Retrieving data ...", true);
}

private void getConversations() {
    try {
        mConversations = new ArrayList<Conversation>();
        Conversation o1 = new Conversation();
        o1.setStatus("SF services");
        o1.setMessage("Pending");           
        mConversations.add(o1);
    } catch (Exception e) {
        Log.e("BACKGROUND_PROC", e.getMessage());
    }
    runOnUiThread(returnRes);
}

private Runnable returnRes = new Runnable() {
    @Override
    public void run() {
        if(mConversations != null && mConversations.size() > 0){
            mAdapter.notifyDataSetChanged();
            for(int i=0;i<mConversations.size();i++)
                mAdapter.add(mConversations.get(i));
        }
        mProgressDialog.dismiss();
        mAdapter.notifyDataSetChanged();
    }
  };

private Handler mHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        int convIndex = msg.arg1;
        int viewTouched = msg.what;
        switch(viewTouched){
            case ConversationAdapter.PROF_ICON:
                showNumber(convIndex);
            break;
            case ConversationAdapter.MESSAGE:
                showMessageDetails(convIndex);
            break;
        }
        super.handleMessage(msg);
    }
};

private void showNumber(int convIndex) {
    Toast.makeText(mContext, "Pressed: "+convIndex, Toast.LENGTH_LONG).show();
}

private void showMessageDetails(int convIndex) {
    final Conversation conv = mConversations.get(convIndex);
    Intent i = new Intent(mContext, DetailsPage.class);
    i.putExtra("someExtra", conv);
    startActivity(i);
}
}

DetailsPage.class

package com.handler.test;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class DetailsPage extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Log.i("Test", "Details Page");      
}


}

Conversation.class:

package com.handler.test;

import java.io.Serializable;

public class Conversation implements Serializable {

private static final long serialVersionUID = -437261671361122258L;

private String status;

public String getStatus() {
    return status;
}
public void setStatus(String status) {
    this.status = status;
}
}

ConversationAdapter.class:

package com.handler.test;

import java.util.ArrayList;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class ConversationAdapter extends ArrayAdapter<Conversation> {

public static final int PROF_ICON = 0;
public static final int MESSAGE = 1;

private Context mContext;
private Handler mHandler;
private ArrayList<Conversation> mItems;
private int mXmlId;

private LinearLayout detailsOfConv;
private ImageView iconImage;

public ConversationAdapter(Context context, int textViewResourceId, ArrayList<Conversation> items, Handler handler) {
    super(context, textViewResourceId, items);
    this.mContext = context;
    this.mItems = items;
    this.mXmlId = textViewResourceId;
    this.mHandler = handler;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(mXmlId, null);
    }
    final Message m = new Message();
    m.arg1 = position;
    Conversation c = mItems.get(position);
    if (c != null) {
        iconImage = (ImageView) v.findViewById(R.id.icon);
        if (iconImage != null) {
            iconImage.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    m.what = PROF_ICON;
                    mHandler.sendMessage(m);
                }
            });
        }

        detailsOfConv = (LinearLayout) v.findViewById(R.id.details);
        if(detailsOfConv != null){
            detailsOfConv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    m.what = MESSAGE;
                    mHandler.sendMessage(m);
                }
            });
        }
    }
    return v;
}
}

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
>
<ListView
 android:id="@+id/android:list"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:cacheColorHint="#00000000"
 />
</LinearLayout>

inbox_row.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="?android:attr/listPreferredItemHeight"
  android:padding="6dip">
  <ImageView
    android:id="@+id/icon"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_marginRight="6dip"
    android:src="@drawable/icon" />
  <LinearLayout
    android:id="@+id/details"
    android:orientation="vertical"
    android:layout_width="0dip"
    android:layout_weight="1"
    android:layout_height="fill_parent">
    <TextView
        android:id="@+id/toptext"
        android:textColor="#99FF66"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:singleLine="true"
        android:text="123456789"
        />       
  </LinearLayout>
</LinearLayout>

1 Ответ

32 голосов
/ 06 ноября 2010

Полагаю, вы отправляете дважды одно и то же сообщение.Действительно, в коде есть один new Message() и два mHandler.sendMessage(m), которые возможно оба выполняются.

Попробуйте создавать новое сообщение при каждой отправке сообщения.

Отредактировано:

Message.obtain () предпочтительнее, чем Сообщение m = новое сообщение () (поскольку оно перерабатывает используемые сообщения под капотом)

В вашем случаеВы можете использовать new.copyFrom (old) , если вам нужна копия существующего сообщения.

...