适配器+线程

时间:2016-04-28 01:31:56

标签: java android multithreading sockets android-asynctask

W/System.err: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

这是我的问题。我正在尝试创建一个聊天,因为我正在使用RecyclerView和套接字,请记住我必须使用套接字(作业的一部分)。所以我打开一个连接并启动一个线程来监听服务器,每次聊天参与者发送一个消息时,它都会向我发送一个消息。我正在使用AsyncTask,其中我连接到服务器,这需要cus我无法在主线程上执行连接。

最后我正在进行某种递归,连接到服务器,等待msg,断开连接,执行onPostExecute以更改itens并再次调用AsyncTask。

问题是adapter.notifyDataSetChanged();并没有做我所说的,我的RecyclerView上的itens没有改变,或者它什么时候再加载所有的Recycler。

我有活动的onCreate,它有正常的东西+ Recyclye初始化程序,然后我打电话:

private void conAtualizer() {
    latch = new CountDownLatch(1);
    Thread Thread = new HandlerThread("Handler") {
        @Override
        public void run() {
            try {
                Socket socketMsg = Conection.persistentConect();
                DataOutputStream outToServer = 
                        new DataOutputStream(socketMsg.getOutputStream());
                BufferedReader servidorAnsw = 
                        new BufferedReader(new 
                                InputStreamReader(socketMsg.getInputStream()));
                outToServer.writeBytes("406" + '\n' + 
                        getIntent().getStringExtra("LOGED_ID")+"\n"+
                        getIntent().getStringExtra("TARGET_ID") + '\n');

                newMsg=false;
                while(active){
                    if(servidorAnsw.ready()){
                        if(servidorAnsw.readLine().equals("406")){
                            MetaMessage thisMetaMessage = 
                                    new MetaMessage(servidorAnsw.readLine());
                            menssages.add(thisMetaMessage);
                            newMsg=true;
                        }
                    }
                }
                outToServer.writeBytes("close\n");
                latch.countDown();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    };
    Thread.start();
    try {
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

通知:

public class NotConv extends AsyncTask <String,Void,MetaMnssage>{

    @Override
    protected MetaMessage doInBackground(String... params) {
        while(!newMsg){
        }
        if(ative){
            adapter.notifyDataSetChanged();
        }
        return null;
    }

    protected void onPostExecute(MetaMessage thisMetaMessage) {
        newMsg=false;
        new NotConv().execute("");
    }
}

1 个答案:

答案 0 :(得分:0)

您未指定错误发生的位置。

但是从错误本身我可以理解你正在尝试从后台进程更新UI视图(意味着一个线程或运行在与另一个主线程不同的东西上。)

正如人们所建议的那样,只有在需要更新视图时才应在线程中使用runOnUiThread()。

另外,为什么要在donInBackground()中执行notifyDataSetChanged()?您可能需要考虑在onPreExecute()或onProgressUpdate()上执行此操作,这应该用于进行UI更改。