2016-03-27 11 views
1

次の問題があります。私はEditTextフィールドを持っているメインスレッドでは、私は無限に受信メッセージのソケットをリッスンAsyncTaskがあります。 (doInBackground()にある)ループではonProgressUpdate()を呼び出して文字列を渡そうとしていて、oPU()が文字列を受け取ってEditTextをメインスレッドに配置したときに表示する必要があります。EditTextをAsyncTaskと無限ループから更新できません

public class ClientSide extends AsyncTask<String, String, String>{ 
    public EditText field = (EditText) findViewById(R.id.bar1); 
    ...} 

最初の問題は、findViewById(R.id.bar1)というシンボルが解決できないということです。何が原因なのか、どうすれば修正できるのか? 2番目の問題はループの問題です。問題は、定期的に新しいスレッドを作成したくないということです。私の場合、ソケットを作成し、オブジェクトが.execute()であるたびにバインドすることを意味します。私のコードを再構成して、より洗練されたソリューションを作る方法を提案してください。私はAsyncTasksが短いプロセスでapp-longではないことを知っていますので、私の現在の解決策(ループあり)は分解するニンジン(a.k.a. bad one)です。 もう一度: 1. findViewById()を実際にEditText UI要素に一致させる方法を教えてください。 2.アプリケーションがバックグラウンドでメッセージリスナーを実行する必要があるたびに、ソケットを作成しないためにコードを再編成する方法はありますか?

あなたにも非同期.. doInBackgroundを見ることができます:

protected String doInBackground(String... params){ 

    final String SERVER_HOSTNAME = "hereGoesMyIP"; 
    final int SERVER_PORT = 2002; 
    BufferedReader mSocketReader; 
    PrintWriter mSocketWriter; 
    final String TAG = ClientSide.class.getSimpleName(); 
    String outputln = "Me. Android"; 


    try { 
     //Initialization of the socket, socket reader and writer. 
     Socket socket = new Socket(SERVER_HOSTNAME, SERVER_PORT); 
     mSocketReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     mSocketWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); 
     System.out.println("Connected to server " + SERVER_HOSTNAME + ":" + SERVER_PORT); 


     //An infinite loop which checks for incoming messages. 
     while(true){ 
      String inMsg=""; 
      String aMessage = ""; 

      //Reads from the socket 
      if((inMsg=mSocketReader.readLine())!=null && socket.isConnected()){ 
       publishProgress(inMsg); 
      } 

      Thread.sleep(500);//still requres try - catch? 
     } 


    } catch (IOException ioe) { 
     System.err.println("Cannot connect to " + SERVER_HOSTNAME + ":" + SERVER_PORT); 
     ioe.printStackTrace(); 

    } 

    return null; 
} 

答えて

1

1)findViewByid()はActivityクラスで接続可メソッドです。 AsyncTaskクラスでは使用できません。だから、あなたがそうあなたのEditTextを更新するprogressupdate()またはpostExecute()メソッドを使用してバックグラウンドスレッドからあなたのビューを更新することはできません覚えておいてください、あなたはこの

EditText editText = yourView.findViewById(R.id.edit_text); 

のようにそれをアセスすることができ、この

private Context mContext; 
private View yourView; 


    public Clientside(Context context, View rootView){ 
     this.mContext=context; 
     this.yourView=rootView; 
    } 

同様AsyncTaskにあなたの視野を通過しますメインスレッドで実行されます。

@Override 
protected void onPostExecute(String result) { 

} 


    View rootView = findViewById(android.R.id.content).getRootView();//This will return you the rootView 



ClientSide cs = new ClientSide(getApplicationContext(),rootView);//do this in your mainactivity 

getApplicationContextは()あなたがしているコンテキストを返します。

ありがとう。私はこれが助けになることを望みます。

+0

ありがとうございますrそのような詳細な答え。私は今あなたのソリューションをテストしています。あなたは2)について何かを持っているなら、私はそれを読んでうれしく思います。もう一度、ありがとうございました。私は最高のあなたの答えをチェックすることを願っています。ちょうどそれを実行するために私に1-2分を与える... – KDX2

+0

2)あなたの質問を理解することができた – Jois

+0

あなたは私にあなたの2番目の質問を教えてくださいできますか? – Jois

1

私はあなたが例えばonProgressUpdate

内のEditTextをリフレッシュする必要があります。この問題を停止すると信じて:

protected void onProgressUpdate(String newText) { 
    field.setText(newText); 
    field.invalidate(); 
} 

し、クライアント内部のメインthread..notに外にフィールド変数を宣言

これはあなたのクライアントサイドにあります。

+0

'field'は'シンボルを解決できません '...それは動作しません。 – KDX2

+0

@ KDX2うん、それは残念です..私はそれを見るのを忘れてしまった。view.findViewByIdを作成する方法はもっと良いと思う.. – sharan

関連する問題