Android的处理器信息和ListView
我现在道歉了很长的帖子,但这是我能解释的唯一途径,而谷歌给出了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>
对不起,所有的代码!
我的猜测是你发送两次相同的信息。事实上,在代码中有一个new Message()
和两个mHandler.sendMessage(m)
可能都执行。
尝试每次发送消息时都会发送一条新消息。
编辑:
Message.obtain()最好Message m = new Message()(因为它回收罩下使用的消息)
在你的情况,如果你需要现有的邮件的副本,您可以使用new.copyFrom(old)。
嗯,这不工作,我试图通过只有一个视图,而不是每次按下onclick节省资源(是一个微不足道的数额)。 我可以看到如果执行这两个操作都会出现错误。但有了布局视图,我不能看到这是可能的,操作系统必须缺少它的清理? 无论哪种方式它现在工作。通过将新的Message()移入onClick。 谢谢! – Blundell 2010-11-06 15:49:06
啊伟大没有没有,谢谢!新消息()更改为Message.obtain() – Blundell 2010-11-06 15:56:08