2016-04-28 11 views
-1
W/System.err: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 

Das ist mein Problem. Ich versuche einen Chat zu erstellen, dafür benutze ich einen RecyclerView und Sockets, bedenke, dass ich Sockets benutzen muss (Teil der Hausaufgaben). Also öffne ich eine Verbindung und starte einen Thread, um auf den Server zu warten, der mir jedes Mal eine Nachricht schickt, wenn ein Chat-Teilnehmer eine Nachricht sendet. Ich verwende eine AsyncTask, in der ich mich mit dem Server verbinde, das ist cus, ich kann keine Verbindungen am Hauptthread machen.Probleme mit Adapter + Gewinde

Am Ende mache ich eine Art Rekursion, verbinden mit dem Server, warten auf eine Nachricht, trennen, führen ein onPostExecute aus, um die itens zu ändern und AsyncTask erneut aufzurufen.

Das Problem ist adapter.notifyDataSetChanged(); Es tut nicht, was ich überprüft habe, itens auf meinem RecyclerView ändert sich nicht, oder wenn es tut, lädt es den ganzen Recycler wieder.

Ich habe die onCreate der Tätigkeit, die die normalen Sachen + Recyclye initializer hat, und dann rufe ich:

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(); 
    } 
} 

Und das mitteilen:

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(""); 
    } 
} 
+0

sollten Sie 'runOnUIThread' verwenden. –

+0

Ich kann keine Verbindung zum Haupt-Thread herstellen. 'runOnUIThread' läuft auf dem Haupt-Thread. –

+0

sollten Sie hier Ihren Code posten, damit every1 helfen kann. –

Antwort

0

Sie nicht angeben, wo Der Fehler tritt auf.

Aber von dem Fehler selbst kann ich verstehen, dass Sie versuchen, Benutzeroberflächenansichten von einem Hintergrundprozess zu aktualisieren (Bedeutung eines Threads oder etwas, das auf einem anderen als dem UI Main Thread ausgeführt wird).

Wie die Leute vorschlagen, sollten Sie runOnUiThread() nur dann in Ihrem Thread verwenden, wenn Sie eine Ansicht aktualisieren müssen.

Auch warum führen Sie notifyDataSetChanged() in donInBackground()? Möglicherweise müssen Sie dies bei onPreExecute() oder onProgressUpdate() berücksichtigen, die verwendet werden sollten, um Änderungen an der Benutzeroberfläche vorzunehmen.

+0

Dies ist die Lösung, die ich gemacht habe, um den Fehler zu umgehen. –

+0

Ich habe versucht, den Adapter mit der Methode conAtualizer() zu aktualisieren, die diesen Fehler generiert hat. conAtualizer läuft weiter und wartet auf eine neue Nachricht vom Server, sie läuft nicht im Hauptthread. Aber NotConv rufe ich den Hauptthread auf, und es wird in Schleife sein, bis ich eine neue Nachricht in ConAtualizer und die Variable NewMsg zu True erhält, die die While-Schleife beendet, den Adapter benachrichtigen und OnPostExecute ausführen, um eine andere Schleife zu starten. –