1

このリンクでコードをコンパイルしようとしています。

次の行でハングアップしているため、コードは機能していません。

textIn.setText(dataInputStream.readUTF());

何らかの理由でハングアップしないのに ハングアップwriteUTF()readUTF()ます。

ここで誰かが私を正しい方向に向けることができますか?

これが私のコードです:

public Socket socket = null;
public DataOutputStream dataOutputStream = null;
public DataInputStream dataInputStream = null;
public Thread readjsonthrd = new Thread(new ReadJSONThread());

private final static String LOG_TAG = AndroidClient.class.getSimpleName();
private final Handler handler = new Handler();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Log.e(LOG_TAG, "Before OnCreate() Try");
    try {
        Log.e(LOG_TAG, "In OnCreate() Try");
        socket = new Socket("23.23.175.213", 9000);
        Log.e(LOG_TAG, "Created Socket");
        dataOutputStream = new DataOutputStream(socket.getOutputStream());
        Log.e(LOG_TAG, "Created DataOutputStream");
        dataInputStream = new DataInputStream(socket.getInputStream());
        Log.e(LOG_TAG, "Created DataInputStream");

        Profile p = new Profile();
        Log.e(LOG_TAG, "Created Profile Instance");

        //Gets the local profile via JSON and converts into Profile type
        Gson gson = new Gson();
        Log.e(LOG_TAG, "Created Gson Instance");
        p = gson.fromJson(p.getProfileJSONStr(), Profile.class);
        Log.e(LOG_TAG, "Converted Profile to JSON");

        //Gson gson = new Gson();
        Log.e(LOG_TAG, "Before: outputJSON = gson.toJson(p);");
        outputJSON = gson.toJson(p);
        Log.e(LOG_TAG, "Created outputJSON");

        dataOutputStream.writeUTF(outputJSON); //OUTPUT OF JSON FROM LOCAL PROFILE BEING SENT TO THE SERVER
        dataOutputStream.flush();
        Log.e(LOG_TAG, "Created dataOutputStream");
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Log.e(LOG_TAG, "Before initEventHandlers");
    initEventHandlers();
    Log.e(LOG_TAG, "Create Thread");
    Thread serverthrd = new Thread(new ServerThread());

    Log.e(LOG_TAG, "Start Thread");
    serverthrd.start();
    Log.e(LOG_TAG, "Started Thread");
}

public class ServerThread implements Runnable { 
    @Override
    public void run() {
        // TODO Auto-generated method stub
    //Socket socket = null;
    //DataOutputStream dataOutputStream = null;
    //DataInputStream dataInputStream = null;
        Log.e(LOG_TAG, "Before Server Try Statement");
    try {
        Log.e(LOG_TAG, "In Server Try Statement");
        //socket = new Socket("23.23.175.213", 1337);

        //dataOutputStream = new DataOutputStream(socket.getOutputStream());
        //dataInputStream = new DataInputStream(socket.getInputStream());
        /*Profile p = null;

        //Gets the local profile via JSON and converts into Profile type
        Gson gson = new Gson();
        p = gson.fromJson(p.getProfileJSONStr(), Profile.class);

        //Gson gson = new Gson();
        outputJSON = gson.toJson(p);
        dataOutputStream.writeUTF(outputJSON); //OUTPUT OF JSON FROM LOCAL PROFILE BEING SENT TO THE SERVER
        */
        //dataOutputStream.writeUTF(textOut.getText().toString());  //OUTPUT JSON GOES HERE
        //textIn.setText(dataInputStream.readUTF());


        Log.e(LOG_TAG, "Start Thread");
        readjsonthrd.start();
        Log.e(LOG_TAG, "Started Thread");
        /*Log.e(LOG_TAG, "Before inputJSON String");
        inputJSON = dataInputStream.readUTF();

        //Convert 
        Log.e(LOG_TAG, "After inputJSON String");
        Log.e(LOG_TAG, "InputJSON:" + inputJSON);*/

        //textIn.setText(dataInputStream.readUTF());  //GET JSON COMING FROM SERVER HERE
        refreshViewModels();
    } /*catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }*/
    finally{
        if (socket != null){
            try {
                socket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if (dataOutputStream != null){
            try {
                dataOutputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if (dataInputStream != null){
            try {
                dataInputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }


    }
}

public class ReadJSONThread implements Runnable { 
    @Override
    public void run() {
        // TODO Auto-generated method stub
    //Socket socket = null;
    //DataOutputStream dataOutputStream = null;
    //DataInputStream dataInputStream = null;
        Log.e(LOG_TAG, "Before Read JSON Try Statement");
        try {
            Log.e(LOG_TAG, "Before inputJSON String");
            inputJSON = dataInputStream.readUTF();

            //Convert 
            Log.e(LOG_TAG, "After inputJSON String");
        }
        catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
4

5 に答える 5

5

1 つの政府 API と統合しているときに、多少似たような問題に直面しました。

サーバーが c にあり、 * で終了または要求文字列を期待していることがわかりました。応答も * で終了します

ソケットの入出力ストリームに直接書き込むことでこれを解決し、** が発生したときに読み取りを終了しました。

        Socket client = new Socket(serverIp, port);
        OutputStream out = client.getOutputStream();
        InputStream in = client.getInputStream();

        String test = "REQUEST-STRING**";
        out.write(test.getBytes());
        out.flush();

        int c;
        while ((c=in.read())!=-1) {
            if (isEndOfResponse(c)) {
                break;
            }
            System.out.print((char)c);
        }
        client.close();
于 2013-04-27T14:46:31.030 に答える
1

それ以外の

readUTF()

もし、あんたが

読み込まれた行()

問題を取り除く必要があります (サーバーが適切に終了した 1 つか 2 つの行を応答として送信したと仮定します)。

注: これをメイン アクティビティ内で実行している場合、ICS 以降では、メイン スレッドでネットワーク接続を開く際に制限の問題が発生します。制限を無効にしないことを選択した場合、1 つの迅速な解決策は asynctask です。これでは、おそらくメイン レイアウト (およびテキストビュー) にアクセスできなくなります。

于 2013-01-10T00:11:08.313 に答える
1

readUTF()ブロッキング ネットワーク コールです。Threadメイン UI ではない別のものから呼び出す必要がありますThread。これが、その例が行う方法です。ブロックしているため、Threadデータを受信するまで電流がハングします。したがって、別のものを与える必要があります。

Android のドキュメントでは、実際にはこれを行うことを具体的に推奨しています。これは、ネットワーク呼び出しで長時間待機しているために「アプリケーションが応答していません」というエラーが表示されるためです。

編集:あなたが与えたコードに基づいて、Thread間違った設定をしているだけです。Thread 自体で Socket を作成する必要があります (または、コンストラクターを介して渡すことができます)。readUTF()にメソッドがあるだけでは、Threadあまり効果がありません。

私の提案は、クラスで and と呼ばれるいくつかのラッパーメソッドを作成し、そこにそれぞれのメソッドを実装するwrite()ことです。次に、メソッドでオブジェクトを作成し、書き込みたいときに を呼び出すことができます。読み取りの場合、メソッドにループを作成し、ネットワークからの読み取りに成功したら、Activity クラスからメソッドを呼び出してデータの処理を実行します。read()ReadJSONThreadSocketonCreate()Thread<thread>.write()read()

于 2012-08-07T06:29:54.243 に答える
0

readUTF()Java 固有です。最初に 2 バイトを読み取り、それを長さとして使用します。次に、バイトを読み取り、それらを変更された UTF-8 として扱います。基本的に、これが機能するには、を使用する Java サーバーが必要ですwriteUTF()

また、UI スレッドで実行時間の長い操作 (= ネットワーク呼び出し) を実行しないでください。これにより、UI の再描画とイベント処理が妨げられるため、アプリが「ハング」したように見えます。バックグラウンド スレッドで実行時間の長いタスクを実行するには、AsyncTaskを使用します。

于 2012-08-07T06:36:57.983 に答える