当我尝试在第一个Activity上从监听器运行第二个Activity时,main.xml有一个致命的异常。当我取出runTcpClient();在TcpClient线程()上加载正常。
我遇到了使用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);
}
}
logcat的
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
答案 0 :(得分: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);
}
}
调用new MyInnerClass()。execute();从你主要的Activity和android会自动调用onPreExecute()在你的网络访问之前做你在wana做的任何事情。
然后,Android将调用doInBackground答案 1 :(得分:1)
Caused by: android.os.NetworkOnMainThreadException
您正尝试在主线程上执行可能较慢的网络操作,这在Android 3.0+中成为致命的例外。只需使用AsyncTask或Loader将runTcpClient()
移动到新线程。
以下是一个示例:How to fix 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();
我还有一个问题。接收消息的
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()
。
答案 2 :(得分:0)
尝试使用Small Piece Of Code.But这不是一个好习惯。
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectNetwork()
.permitNetwork() //permit Network access
.build());
您可以使用AsynTask或任何线程概念。 Its May Help