2012-11-28 47 views
2

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

我不明白这是为什么?有谁能帮我澄清一下吗?我也有理解如何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); 
} 
} 
+0

你可以发布你的AndroidManifest.xml文件吗? –

+0

register()函数是从哪里调用的? –

+1

您需要在doInBackground中进行网络通话。您的方法writeToStream和readFromStream在UI线程上执行,而不是在AsyncTask线程上执行。 http://developer.android.com/reference/android/os/AsyncTask.html – alex

回答

-2
android.os.NetworkOnMainThreadException 

这eror带有蜂窝(3.0或更高版本)。

如文档所述,您无法在其主线程上执行联网操作。骑这个你必须使用处理程序或asynctask。 AFAIK没有其他办法可以做到。

您可以了解更多详情WHY ICS Crashes your App

看到这个尝试使用下面的代码片段

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

但我的控制器是一个asynctask,并且即时调用它的方法。 –

-1

有此问题的两个解决方案。

1)不要在主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; 
+0

我调用方法的控制器是asynctask –

+0

@ user1853395发布您的完整代码。 –

相关问题