0

私は、ユーザーがサーバーに送信される文字列を入力するクライアントで構成される非常に単純なアプリを構築しています。次に、サーバーはメッセージを受信すると、同じメッセージをクライアントに送り返します。私の問題は、サーバーから送信されたメッセージを読み込もうとすると、クライアントでエラーが発生することです。

ソケットが開かれると、次のスニペットは、クライアントがメッセージを送受信しようとする方法を示しています。

PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
                      .getOutputStream())),true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

out.println(message);

if (in.readLine()!=null)


    response=in.readLine();

「in」変数(in.readLine())を読み取るときに、strictMode $ AndroidBlockGuardPolicy.onNetwork()例外が発生します

サーバー側は次のとおりです。

while ((line = in.readLine()) != null) {
                            final String line2=line;
                            handler.post(new Runnable() {
                                @Override
                                public void run() {
                                    serverStatus.setText(line2);
                                }
                            });
                            out.println("Message received:"+line2);

私が欲しいのは、サーバー上のメッセージが受信されたことを確認するメッセージをクライアントに送信することだけです。私が直面しているもう1つの問題は、サーバーがメッセージを受信し、それを読み取ってクライアントに送り返すまでの時間を確保する必要があるため、クライアントはおそらく1秒待つ必要があるということです。この目的のために何を使用できますか?睡眠方法は適切でしょうか?

Thread.sleep(1000);

また

systemClock.sleep(1000);

前もって感謝します

[アップデート]

これはクライアントのコードです:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_client);

    serverIp = (EditText) findViewById(R.id.server_ip);
    connectPhones = (Button) findViewById(R.id.connect_phones);
    connectPhones.setOnClickListener(connectListener);

    messageServer = (EditText) findViewById(R.id.message);
    communicatePhones = (Button) findViewById(R.id.send_message);
    messageServer.setVisibility(View.GONE);
    communicatePhones.setVisibility(View.GONE);


}

private OnClickListener connectListener = new OnClickListener() {

    @Override
    public void onClick(View v) {
        if (!connected) {
            serverIpAddress = serverIp.getText().toString();
            if (!serverIpAddress.equals("")) {
                Thread cThread = new Thread(new ClientThread());
                cThread.start();
            }
        }
    }
};

public class ClientThread implements Runnable {

    public void run() {
        try {
            Log.d("ClientActivity", serverIpAddress);
            InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
            Log.d("ClientActivity", "C: Connecting...");
            socket = new Socket(serverAddr, ServerActivity.SERVERPORT);

            handler.post(new Runnable() {
                  @Override
                  public void run() {
                      serverIp.setVisibility(View.GONE);
                      connectPhones.setVisibility(View.GONE);
                      messageServer.setVisibility(View.VISIBLE);
                      communicatePhones.setVisibility(View.VISIBLE);

                      communicatePhones.setOnClickListener(communicateListener);

                      mensajeRecibido = (TextView) findViewById(R.id.mensaje_recibido);
                      mensajeRecibido.append(response);
                  }
            });
            //socket.close();
            Log.d("ClientActivity", "C: Closed.");
        } catch (Exception e) {
            Log.e("ClientActivity", "C: Error", e);
            connected = false;
        }
    }

    private OnClickListener communicateListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            message = messageServer.getText().toString();
            if (!serverIpAddress.equals("")) {
                try {
                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
                            .getOutputStream())), true);        

                    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    out.println(message);
                    Log.d("ClientActivity", "C: Sent.");
                    //Thread.sleep(6000);
                    SystemClock.sleep(2000);
                  /*  handler.postDelayed(new Runnable() { 
                         public void run() { 
                              my_button.setBackgroundResource(R.drawable.defaultcard); 
                         } 
                    }, 2000); */
                    if (in.readLine()!=null)
                        response=in.readLine();

                } catch (IOException e) {
                    Log.e("ClientActivity", "S: Error", e);
                }              
            }
        }
    };
}

}

通信リスナーのOnClickListenerオブジェクトはどこに作成する必要がありますか?runメソッド内に配置しようとしましたが、不明なcommunicationListener変数や無効なプライベート修飾子などのエラーが発生しました。

4

1 に答える 1

1

メインスレッドではないスレッドを介してGUI要素にアクセスすることを想定していないことをご存知ですか?

そして、メインスレッドを介してネットワークにアクセスするのは悪い習慣です... communicationListenerは私にはすべて間違っているように見えます...それはGUIスレッドで実行されていますか、それともClientThreadで実行されていますか?onClickイベントとしてGUIスレッドで実行することを想定していますが、内部のロジックはネットワークスレッドのように見えます。

メインスレッド(GUIスレッド)はネットワークスレッドにメッセージを送信する必要があります(ハンドラーを使用して送信するか、メインスレッドのデータメンバーになることができるネットワークスレッドのメソッドを呼び出すだけですが、onClickはメインスレッドに実装されています!)。

于 2013-02-04T15:23:06.443 に答える