-1

重複の可能性:
android.os.NetworkOnMainThreadException

1 番目のアクティビティのリスナーから 2 番目のアクティビティを実行しようとすると、main.xml に致命的な例外が発生します。runTcpClient(); を取り出すと TcpClient Thread() では問題なくロードされます。

aSyncTask を使用して管理する UI スレッドに出くわしました: Android UI aSyncTask

TcpClientJava.java のコード

package com.mesger;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;



public class TcpClient extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    runTcpClient();
    finish();
}

private static final int TCP_SERVER_PORT = 1234;
private void runTcpClient() {
    try {
        Socket s = new Socket("10.0.2.2", TCP_SERVER_PORT);
        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        //send output msg
        String outMsg = "TCP connecting to " + TCP_SERVER_PORT + System.getProperty("line.separator"); 
        out.write(outMsg);
        out.flush();
        Log.i("TcpClient", "sent: " + outMsg);
        //accept server response
        String inMsg = in.readLine() + System.getProperty("line.separator");
        Log.i("TcpClient", "received: " + inMsg);
        //close connection
        s.close();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } 
}
//replace runTcpClient() at onCreate with this method if you want to run tcp client as a service
private void runTcpClientAsService() {
    Intent lIntent = new Intent(this.getApplicationContext(), TcpClientService.class);
    this.startService(lIntent);
}

}

ログキャット

11-12 13:41:22.725: D/gralloc_goldfish(738): Emulator without GPU emulation detected.
11-12 13:42:32.409: D/AndroidRuntime(738): Shutting down VM
11-12 13:42:32.409: W/dalvikvm(738): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
11-12 13:42:32.465: E/AndroidRuntime(738): FATAL EXCEPTION: main
11-12 13:42:32.465: E/AndroidRuntime(738): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.i911.emergency.response/com.mesger.TcpClient}: android.os.NetworkOnMainThreadException
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.os.Handler.dispatchMessage(Handler.java:99)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.os.Looper.loop(Looper.java:137)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread.main(ActivityThread.java:4745)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.lang.reflect.Method.invokeNative(Native Method)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.lang.reflect.Method.invoke(Method.java:511)
11-12 13:42:32.465: E/AndroidRuntime(738):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
11-12 13:42:32.465: E/AndroidRuntime(738):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-12 13:42:32.465: E/AndroidRuntime(738):  at dalvik.system.NativeStart.main(Native Method)
11-12 13:42:32.465: E/AndroidRuntime(738): Caused by: android.os.NetworkOnMainThreadException
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
11-12 13:42:32.465: E/AndroidRuntime(738):  at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
11-12 13:42:32.465: E/AndroidRuntime(738):  at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
11-12 13:42:32.465: E/AndroidRuntime(738):  at libcore.io.IoBridge.connect(IoBridge.java:112)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.Socket.startupSocket(Socket.java:566)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.Socket.tryAllAddresses(Socket.java:127)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.Socket.<init>(Socket.java:177)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.Socket.<init>(Socket.java:149)
11-12 13:42:32.465: E/AndroidRuntime(738):  at com.mesger.TcpClient.runTcpClient(TcpClient.java:32)
11-12 13:42:32.465: E/AndroidRuntime(738):  at com.mesger.TcpClient.onCreate(TcpClient.java:25)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.Activity.performCreate(Activity.java:5008)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
11-12 13:42:32.465: E/AndroidRuntime(738):  at     android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
11-12 13:42:32.465: E/AndroidRuntime(738):  ... 11 more
4

3 に答える 3

2

メインスレッドからネットワークに触れないでください。ネットワーク操作用にAsyncTaskを実装します。

   private class MyInnerClass extends AsyncTask<String, Void, String> {
       @Override
       protected void onPreExecute() {
       super.onPreExecute();

       }

       @Override
       protected String doInBackground(String params) {

       return "Done";
       }

       @Override
       protected void onPostExecute(String result) {
       super.onPostExecute(result);
       }
   }

新しいMyInnerClass()。execute();を呼び出します。あなたからメインのアクティビティとAndroidは自動的にonPreExecute()を呼び出し、ネットワークにアクセスする前にこのメソッド内で実行したいことをすべて実行します。

次に、AndroidはdoInBackgroundを呼び出し
ます。doInBackground()内のネットワーク関連のものを呼び出します。終了すると、自動的にonPostExecute()を呼び出し、結果がパラメーターとしてこのメ​​ソッドに渡されます。

于 2012-11-12T19:11:47.690 に答える
1
Caused by: android.os.NetworkOnMainThreadException

メイン スレッドで潜在的に低速なネットワーク操作を実行しようとしています。これは Android 3.0 以降で致命的な例外になりました。runTcpClient()AsyncTask またはローダーを使用して、新しいスレッドに移動するだけです。

以下に例を示します: android.os.NetworkOnMainThreadException を修正するには? .


これを試して:

class TcpClientTask extends AsyncTask<Void, Void, Void> {
    private static final int TCP_SERVER_PORT = 1234;
    private boolean error = false;

    protected Void doInBackground(Void... arg0) {
        try {
            Socket s = new Socket("10.0.2.2", TCP_SERVER_PORT);
            BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            //send output msg
            String outMsg = "TCP connecting to " + TCP_SERVER_PORT + System.getProperty("line.separator"); 
            out.write(outMsg);
            out.flush();
            Log.i("TcpClient", "sent: " + outMsg);
            //accept server response
            String inMsg = in.readLine() + System.getProperty("line.separator");
            Log.i("TcpClient", "received: " + inMsg);
            //close connection
            s.close();
        } catch (UnknownHostException e) {
            error = true;
            e.printStackTrace();
        } catch (IOException e) {
            error = true;
            e.printStackTrace();
        }
        return null;
    }

    protected void onPostExecute() {
        if(error) {
            // Something bad happened
        }
        else {
            // Success
        }

    }
}

それを使用するには、次のように呼び出します。new TcpClientTask().execute();


もう1つ質問があります。String inMsg = in.readLine() + System.getProperty("line.separator");メッセージを受信する場合、15msごとに取得するように設定する方法、またはデータを受信し続けるために安定しているものを設定する方法を教えてください。

あなたが何をしようとしているのかわからない。しかし、一度だけ呼び出していることに気付きました。readLine()複数行を読みたい場合は、ループを使用してください。

StringBuilder msg = new StringBuilder();
String line;
while((line = in.readLine()) != null) // Keep reading until the end of the file is reached
    msg.append(in.readLine()).append(System.getProperty("line.separator"));

StringBuilders は、文字列を一緒に追加するときのオーバーヘッドを少なくしmsg.toString()ます。メッセージ全体を取得したいときに使用するだけです。

于 2012-11-12T19:03:47.000 に答える
0

コードの小さな断片を使用してみてください。しかし、それは良い習慣ではありません。

    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
   .detectNetwork()
   .permitNetwork() //permit Network access 
   .build());

AsynTask または任意のスレッド コンセプトを使用できます。 その5月の助け

于 2012-11-12T19:12:28.873 に答える