【问题标题】:android asynctask NetworkOnMainThreadExceptionandroid asynctask NetworkOnMainThreadException
【发布时间】:2012-11-16 06:20:33
【问题描述】:

我正在尝试使用套接字在 android 中编写服务器/客户端应用程序,并且我在 AsyncTask 中处理客户端套接字(服务器不是 android,只是普通的 java)。当我尝试阅读时出现异常从服务器。我发现当我从 android manifest 中删除 android:targetSdkVersion="16" 时,异常消失了,我可以从服务器读取。

我不明白这是为什么?谁能帮我澄清一下?我也很难理解 asynctask 方法 doInBackground 和我自己的方法之间的关系。 conhandler.execute() 是否运行 doInBackground() 然后等到我调用其他方法?感谢您的帮助。

public class ConnectionHandler extends AsyncTask<Void, Void, Void>{

public static String serverip = "10.0.2.2";
public static int serverport = 5000;
Socket s;
PrintWriter out;
BufferedReader in;

protected Void doInBackground(Void... params) {
    try {
        s = new Socket(serverip, serverport);
        Log.i("AsyncTank", "doInBackgoung: Created Socket");
    }...
    if (s.isConnected()) {
    try {
        in = new BufferedReader(new InputStreamReader(s.getInputStream()));
        out = new PrintWriter(s.getOutputStream(), true);
        Log.i("AsyncTank", "doInBackgoung: Socket created, Streams assigned");

    } ....
 }

public void writeToStream(String message) {
 try {
     if (s.isConnected()){
        out.println(message);
    } else {
        Log.i("AsynkTask", "writeToStream : Cannot write to stream, Socket is closed");
    }
    } catch (Exception e) {
    Log.i("AsynkTask", "writeToStream : Writing failed");
   }  
 }

 public String readFromStream() {
try {
    if (s.isConnected()) {
        Log.i("AsynkTask", "readFromStream : Reading message");
        String ret=in.readLine();
        Log.i("AsynkTask", "readFromStream : read "+ret);
        return ret;
    } else {
        Log.i("AsynkTask", "readFromStream : Cannot Read, Socket is closed");
    }
} catch (Exception e) {
    Log.i("AsynkTask", "readFromStream : Reading failed"+e.getClass());
}
return null;
}
}

这是我的主要活动

  public class MainActivity extends Activity {
private EditText view_email;
private EditText view_password;
TextView result;
ConnectionHandler conhandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    conhandler = new ConnectionHandler();
    conhandler.execute();       
    }


public void register(View view) {
     view_email= (EditText) findViewById(R.id.email);
    view_password = (EditText) findViewById(R.id.password);
    String email=view_email.getText().toString();
    String password=view_password.getText().toString();
    conhandler.writeToStream("register");
    conhandler.writeToStream(email);
    conhandler.writeToStream(password);
    String res=conhandler.readFromStream(); //here's the exception
    result=(TextView) findViewById(R.id.result);
    result.setText(res);
 }
 }

【问题讨论】:

标签: android sockets android-asynctask


【解决方案1】:
 android.os.NetworkOnMainThreadException

此错误来自 HoneyComb(3.0 或更高版本)。

您不能按照文档所述在其主线程上执行网络操作。要解决此问题,您必须使用处理程序或异步任务。 AFAIK 没有其他方法可以做到这一点。

您可以查看更多详情WHY ICS Crashes your App

尝试使用下面的代码片段

new Thread(){
    public void run(){
        //do your Code Here    
    }
}.start();

【讨论】:

    【解决方案2】:

    这个问题有两种解决方案。

    1) 不要在 Main UIThread 中编写网络调用,为此使用异步任务。

    2) 在 setContentView(R.layout.activity_main); 之后将以下代码写入 MainActivity 文件中;

    if (android.os.Build.VERSION.SDK_INT > 9) {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
    }
    

    下面的 import 语句到你的 java 文件中。

    import android.os.StrictMode;
    

    【讨论】:

    • 我正在调用该方法的处理程序是异步任务
    猜你喜欢
    • 2015-01-01
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    相关资源
    最近更新 更多