【问题标题】:Updating View from within a Socket.IO thread从 Socket.IO 线程中更新视图
【发布时间】:2015-10-24 22:21:58
【问题描述】:

我想是时候向我的 stackoverbros 提问了。我正在使用 socket.io-client.java https://github.com/nkzawa/socket.io-client.java 使用 socket.io 与我的节点服务器通信。到目前为止,连接工作正常。

这里是 onCreate 和变量定义。

    class Text
{
    String username;
    String message;
}

Socket socket;
ListView listView;
ArrayList<Text> texts = new ArrayList<Text>();
String username = "";

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    listView = (ListView) findViewById(R.id.listView);
    initList();
    activateEnter();
    try {
        startSocket();
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
}

这是创建套接字的函数。

    private void startSocket() throws URISyntaxException
{
    socket = IO.socket("http://localhost");
    socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() 
    {
      @Override
      public void call(Object... args) 
      {
        socket.emit("adduser", "");
      }
    }).on("chat_msg", new Emitter.Listener() 
    {
      @Override
      public void call(Object... args) 
      {
          JSONObject obj = (JSONObject)args[0];
          try {
            String uname = obj.getString("username");
            String msg = obj.getString("msg");
            updateList(uname, msg);
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
      }
    }).on("username", new Emitter.Listener() 
    {
          @Override
          public void call(Object... args) 
          {
              JSONObject obj = (JSONObject)args[0];
              try {
                username = obj.getString("username");
            } catch (JSONException e) {
                e.printStackTrace();
            }
          }
    }).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() 
    {
      @Override
      public void call(Object... args) 
      {

      }

    });
    socket.connect();
}

现在,我有一个聊天功能,聊天消息通过我创建的自定义适配器进入一个 ListView,在套接字函数之外,就像这样。

class FancyAdapter extends ArrayAdapter<Text>
{
     FancyAdapter()
     {
         super(MainActivity.this, android.R.layout.simple_list_item_1, texts);
     }

     public View getView(int position, View convertView, ViewGroup parent)
     {
         ViewHolder holder;
         if(convertView == null)
         {
             LayoutInflater inflater = getLayoutInflater();
             convertView = inflater.inflate(R.layout.text, null);
             holder = new ViewHolder(convertView);
             convertView.setTag(holder);
         }
         else
         {
             holder = (ViewHolder) convertView.getTag();
         }
         holder.populateFrom(texts.get(position));
         return(convertView);
     }
}

class ViewHolder
{
     public TextView text_username = null;
     public TextView text_message = null;

     ViewHolder(View row)
     {
         text_username = (TextView) row.findViewById(R.id.text_username);
         text_message = (TextView) row.findViewById(R.id.text_message);
     }
     void populateFrom(Text w)
     {
         text_username.setText(w.username);
         text_message.setText(w.message);
     }
}

FancyAdapter adapter = null;

private void initList()
{
      adapter = new FancyAdapter();
      listView.setAdapter(adapter);
}

private void updateList(String uname, String message)
{
    Text text = new Text();
    text.username = uname;
    text.message = message;
    texts.add(text); 
    adapter.notifyDataSetChanged();
}

现在,当我从套接字调用(特别是“chat_message”)中调用 updateList(string, string) 时,我得到“ViewRootImpl$CalledFromWrongThreadException 只有创建视图层次结构的原始线程才能接触其视图。”

哦,好吧,我尝试在套接字函数的 EVENT_CONNECT 事件中移动列表/适配器相关的函数和类,但似乎其中定义的内容不会为“chat_message”等其他事件定义。

所以我不知道该怎么办。

【问题讨论】:

    标签: java android sockets websocket socket.io


    【解决方案1】:

    您只能从 UI 线程与视图交互试试这个:

    MyActivity.this.runOnUiThread(new Runnable() {
    
          @Override
          public void run() {
              updateList(uname, msg);
          }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-02
      • 1970-01-01
      相关资源
      最近更新 更多