2010-11-06 92 views
9

我現在道歉了很長的帖子,但這是我能解釋的唯一途徑,而谷歌給出了3頁的結果不是決定性的Android的處理器信息和ListView

這裏是我的錯誤的傢伙:

*** 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參數發送一個消息給一個Handler。 點擊我的其中一個元素激發了開始新活動的意圖。 點擊另一個顯示祝酒。 當這些按下組合時,我得到上述錯誤。即點擊文字來激發意圖,(然後按回),然後點擊圖片顯示敬酒,然後當你點擊文本再次激發意圖時,我得到了FC。

我創建了再現這樣的演示項目: http://rapidshare.com/files/429227042/HandlerTest.rar

這裏是下面的代碼,我試圖刪除儘可能多的克魯夫特,我可以去錯誤的骨頭:

如果你想在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> 

對不起,所有的代碼!

回答

32

我的猜測是你發送兩次相同的信息。事實上,在代碼中有一個new Message()和兩個mHandler.sendMessage(m)可能都執行。

嘗試每次發送消息時都會發送一條新消息。

編輯:

Message.obtain()最好Message m = new Message()(因爲它回收罩下使用的消息)

在你的情況,如果你需要現有的郵件的副本,您可以使用new.copyFrom(old)

+0

嗯,這不工作,我試圖通過只有一個視圖,而不是每次按下onclick節省資源(是一個微不足道的數額)。 我可以看到如果執行這兩個操作都會出現錯誤。但有了佈局視圖,我不能看到這是可能的,操作系統必須缺少它的清理? 無論哪種方式它現在工作。通過將新的Message()移入onClick。 謝謝! – Blundell 2010-11-06 15:49:06

+0

啊偉大沒有沒有,謝謝!新消息()更改爲Message.obtain() – Blundell 2010-11-06 15:56:08