Android 适配器的内容已更改,但ListView未收到通知。(输出主线程的进给列表)

Android 适配器的内容已更改,但ListView未收到通知。(输出主线程的进给列表),android,multithreading,listview,adapter,notifydatasetchanged,Android,Multithreading,Listview,Adapter,Notifydatasetchanged,我正在开发一个聊天应用程序,保存聊天日志的我的适配器(BaseAdapter)正在使用中,因为提供IRC资源的变量正在使用中。绑定活动时,my chat fragments从服务获取适配器。 起初,我试图从适配器本身通知DataSetChanged(),然后我发现需要从主UI线程调用它。因此,我向片段发送广播以通知内部适配器,片段使用主UI线程。 现在,我遇到了这个问题,因为我在UI线程外部(从服务)提供列表,并在主线程上通知它。但它在服务中需要这个适配器。 我该怎么办 这是我的适配器。每个对话

我正在开发一个聊天应用程序,保存聊天日志的我的适配器(BaseAdapter)正在使用中,因为提供IRC资源的变量正在使用中。绑定活动时,my chat fragments从服务获取适配器。 起初,我试图从适配器本身通知DataSetChanged(),然后我发现需要从主UI线程调用它。因此,我向片段发送广播以通知内部适配器,片段使用主UI线程。 现在,我遇到了这个问题,因为我在UI线程外部(从服务)提供列表,并在主线程上通知它。但它在服务中需要这个适配器。 我该怎么办

这是我的适配器。每个对话都有一个。此适配器仍在使用中:

public class Conversa extends BaseAdapter {

private Context context;
public ArrayList<String> log;
private String target;

public Conversa(Context context, String target) {
    this.context = context;
    this.target = target;
    log = new ArrayList<String>();
}

@Override
public int getCount() {
    return log.size();
}

@Override
public Object getItem(int pos) {
    return log.get(pos);
}

@Override
public long getItemId(int arg0) {
    return 0;
}

@Override
public View getView(int pos, View convertView, ViewGroup parent) {
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.msg_layout, parent, false);
    }

    TextView msg = (TextView) convertView.findViewById(R.id.msg);
    msg.setText(log.get(pos));

    return convertView;
}

public ArrayList<String> getLog() {
    return log;
}

public String getTarget() {
    return target;
}

public void setTarget(String target) {
    this.target = target;
}
}

这只是服务上的接收消息方法和适配器变量:

private List<Conversa> pvts;
private Conversa canal;
private UserList userList;


public void receivePVTMessage(String target, String nick, String msg) {

    Conversa pvt = getConversa(target);

    if (pvt == null) {
        addPVTConversa(target);
        pvt = getConversa(target);
    }

    pvt.log.add(Colors.removeFormattingAndColors("<" + nick + "> " + msg));

    // é dessa forma que o fragment fará o notifydatasetchanged na UI
    // thread, a categoria define qual fragment sera atualizado.
    Intent it = new Intent(IRCService.ACTION_RECEIVE_MSG);
    it.addCategory(target);
    sendBroadcast(it);

}

/**
 * Metodo usado para adicionar mensagens de usuarios na janela do chat
 */
public void receiveChatMessage(String nick, String msg) {
    canal.log
            .add(Colors.removeFormattingAndColors("<" + nick + "> " + msg));

    // é dessa forma que o fragment fará o notifydatasetchanged na UI
    // thread, a categoria define qual fragment sera atualizado.
    Intent it = new Intent(IRCService.ACTION_RECEIVE_MSG);
    it.addCategory(IRCService.CANAL);
    sendBroadcast(it);

}

/**
 * Metodo usado para adicionar mensagens gerais na janela do chat
 */
public void receiveChatMessage(String msg) {
    canal.log.add(Colors.removeFormattingAndColors(msg));

    // é dessa forma que o fragment fará o notifydatasetchanged na UI
    // thread, a categoria define qual fragment sera atualizado.
    Intent it = new Intent(IRCService.ACTION_RECEIVE_MSG);
    it.addCategory(IRCService.CANAL);
    sendBroadcast(it);

}
私人列表pvt;
私人康瓦运河;
私有用户列表用户列表;
public void receivePVTMessage(字符串目标、字符串缺口、字符串消息){
Conversa pvt=getConversa(目标公司);
如果(pvt==null){
addPVTConversa(目标公司);
pvt=getConversa(目标);
}
pvt.log.add(Colors.removeformatingandcolors(“+msg”);
//形式上的改变导致了碎片的破坏
//线程,一个分类定义了优质片段血清atualizado。
意向it=新意向(IRCService.ACTION\u RECEIVE\u MSG);
it.addCategory(目标);
发送广播(it);
}
/**
*我希望你能和我谈谈
*/
public void receiveChatMessage(字符串nick,字符串msg){
canal.log
.add(Colors.removeformatingandcolors(“+msg”);
//形式上的改变导致了碎片的破坏
//线程,一个分类定义了优质片段血清atualizado。
意向it=新意向(IRCService.ACTION\u RECEIVE\u MSG);
it.addCategory(IRCService.CANAL);
发送广播(it);
}
/**
*梅托多·乌萨多·帕拉阿迪西奥纳·杰拉斯·珍妮拉·杜查特
*/
public void receiveChatMessage(字符串消息){
canal.log.add(Colors.removeformatingandcolors(msg));
//形式上的改变导致了碎片的破坏
//线程,一个分类定义了优质片段血清atualizado。
意向it=新意向(IRCService.ACTION\u RECEIVE\u MSG);
it.addCategory(IRCService.CANAL);
发送广播(it);
}
同样的事情也发生在我的消息日志列表和我的用户列表(尼克列表)上。userlist适配器也在服务中,我有一个listfragment来显示它;
在这两种情况下,我都从服务更新ArrayList,并通过sendBroadcast()通知它们适配器,并接收保存适配器的片段

我通过使用处理程序访问主线程来完成我需要的操作。
Handler=newhandler(Looper.getMainLoop)

没有任何代码很难说。虽然它可能会工作,但我认为您使用的是一个危险的结构。理想的情况是服务发布一条消息,然后在您的活动中,您获得该消息并填写适配器(您可以使用已经编码的广播消息来发送新的消息数据,而不是无效请求)。无论如何,您得到的错误意味着适配器内容已更改,并且您尚未调用notifyDataSetChanged():ListView已检测到自身内容已更改为“后门”。这破坏了ListView的内部结构。每当我更新列表时,我都会发送广播来通知数据。问题在于多线程。但即使活动已关闭,我也需要接收消息。服务必须接收消息。适配器必须在服务中。我正在尝试从处理程序获取对UI线程的访问权限,但不确定是否有效…我只能向handleMessage()方法发送1个参数…:(
private List<Conversa> pvts;
private Conversa canal;
private UserList userList;


public void receivePVTMessage(String target, String nick, String msg) {

    Conversa pvt = getConversa(target);

    if (pvt == null) {
        addPVTConversa(target);
        pvt = getConversa(target);
    }

    pvt.log.add(Colors.removeFormattingAndColors("<" + nick + "> " + msg));

    // é dessa forma que o fragment fará o notifydatasetchanged na UI
    // thread, a categoria define qual fragment sera atualizado.
    Intent it = new Intent(IRCService.ACTION_RECEIVE_MSG);
    it.addCategory(target);
    sendBroadcast(it);

}

/**
 * Metodo usado para adicionar mensagens de usuarios na janela do chat
 */
public void receiveChatMessage(String nick, String msg) {
    canal.log
            .add(Colors.removeFormattingAndColors("<" + nick + "> " + msg));

    // é dessa forma que o fragment fará o notifydatasetchanged na UI
    // thread, a categoria define qual fragment sera atualizado.
    Intent it = new Intent(IRCService.ACTION_RECEIVE_MSG);
    it.addCategory(IRCService.CANAL);
    sendBroadcast(it);

}

/**
 * Metodo usado para adicionar mensagens gerais na janela do chat
 */
public void receiveChatMessage(String msg) {
    canal.log.add(Colors.removeFormattingAndColors(msg));

    // é dessa forma que o fragment fará o notifydatasetchanged na UI
    // thread, a categoria define qual fragment sera atualizado.
    Intent it = new Intent(IRCService.ACTION_RECEIVE_MSG);
    it.addCategory(IRCService.CANAL);
    sendBroadcast(it);

}