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

これは私の問題です。私はチャットを作成しようとしています。私はRecyclerViewとソケットを使用していますので、ソケット(宿題の一部)を使用しなければならないことに留意してください。だから、私は接続を開いて、サーバーを待ち受けるスレッドを開始します。これは、チャット参加者がmsgを送信するたびにmsgを送信します。私はサーバーに接続するAsyncTaskを使用しています。これは、メインスレッド上で接続を行うことはできません。アダプター+スレッドの問題

最後に、何らかの再帰を行い、サーバーに接続し、メッセージを待ってから切断し、onPostExecuteを実行してitensを変更し、AsyncTaskを再度呼び出します。

問題はadapter.notifyDataSetChanged()です。私はRecyclerView上でitensが変わっていないか、それがすべてのRecyclerを再びロードするときに、Iveが捉えたことをしません。

私は通常のもの+ Recyclye初期化子を持って活動するのonCreateを、持っている、そして私が呼ぶ:

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

あなたは 'runOnUIThread'を使うべきです。 –

+0

メインスレッドで接続できません。 'runOnUIThread'はメインスレッド上で動作します。 –

+0

ここにあなたのコードを載せるべきで、every1が助けてくれるでしょう。 –

答えて

0

あなたが場所を指定しませんでしたエラーが発生します。

しかし、エラー自体から、UIビューをバックグラウンドプロセス(スレッドまたはUIメインスレッドとは別のスレッドで動作するもの)から更新しようとしていることがわかります。

提案されているように、ビューを更新する必要がある場合にのみ、スレッドでrunOnUiThread()を使用する必要があります。

なぜdonifyBackground()でnotifyDataSetChanged()を実行しますか? UIの変更を行うために使用されるonPreExecute()またはonProgressUpdate()でこれを考慮する必要があります。

+0

これはIveがエラーを回避するために作った解決策です。 –

+0

私は、そのエラーを生成したconAtualizer()メソッドでアダプタを更新しようとしていました。 conAtualizerは稼働を続け、サーバーからの新しいmsgを待って、メインスレッドで実行されません。しかしNotConv私はメインスレッドを呼び出し、conAtualizerとnewMsgの新しいメッセージを受け取るまでwhileループを停止し、アダプタに通知してonPostExecuteを実行して別のループを開始するまでループします。 –

関連する問題