【问题标题】:problems with adapter + threads适配器+螺纹的问题
【发布时间】:2016-04-28 01:31:55
【问题描述】:
W/System.err: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

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

最后我做了某种递归,连接到服务器,等待一个消息,断开连接,执行一个 onPostExecute 来改变它并再次调用 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("");
    }
}

【问题讨论】:

  • 你应该使用runOnUIThread
  • 我无法在主线程上执行连接。 runOnUIThread 在主线程上运行。
  • 您应该在此处发布您的代码,以便every1 可以提供帮助。
  • 好的,我已经编辑了主帖

标签: java android multithreading sockets android-asynctask


【解决方案1】:

您没有指定错误发生的位置。

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

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

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

【讨论】:

  • 这是我为解决该错误所做的解决方案。
  • 我试图在 conAtualizer() 方法中更新适配器,这会产生该错误。 conAtualizer 一直在运行,等待来自服务器的新消息,它不在主线程中运行。但是 NotConv 我在主线程中调用,它将一直处于循环状态,直到我在 conAtualizer 接收到一个新的 msg 并且变量 newMsg 为 true,这将停止 while 循环,通知适配器并运行 onPostExecute 以启动另一个循环。
猜你喜欢
  • 1970-01-01
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
相关资源
最近更新 更多