意识到网络线程可能会对我的UI线程造成破坏,我经历了创建自定义处理程序和自定义线程的整个过程,用于在我的应用程序和远程服务器之间进行TCP/IP网络ping pong命令和响应。效果很好。(您将在下面的代码中看到它被引用为mainCommunicationThread(controlCommands);
)
然而,在触发该线程/处理程序之前,我从SQL中提取IP或主机名(称为currIPstr),然后将其与其他变量一起发送到线程/处理程序。
但是,我需要做的一件事是确保它要么是A)有效的IP地址,要么是B)主机名已解析--否则,甚至开始尝试都没有意义。
好的,没问题,我只需调用此函数:
currIP = InetAddress.getByName(currIPstr).toString().split("/")[1];
我刚刚发现的是,如果运行Gingerbread或StrictMode,上面的代码会触发令人恐惧的NetworkOnMainThreadException。
对,就是那个简单的InetAddress.getByName调用就足够了。我一直在试图找到解决方法,所以我将整个函数移动到了一个可运行的内部:
private String currStatIP = null;
private String currentStatIPstr = null;
private Integer currentStatIDstr = -1;
private String currentPort = null;
private String currentLocation = null;
private String currUserName = null;
private String currPassword = null;
private Integer currStatID = -1;
public void StatControl(Cursor c, final String[] commandtosend){
/*the object will always start off with the first 4 fields being the current login information.
* [0] = IP Address
* [1] = port number
* [2] = username
* [3] = password
* [4] = COMMAND -- this will be used in a switchcase inside the pingpong to decide what to do.
* -- if the Socket is not open, the first 4 fields will be used to re-initiate the connection
* -- otherwise, the command is drawn from this field and sent directly.
* */
currentStatIDstr = c.getInt(0);
currentStatIPstr = c.getString(1);
currentPort = c.getString(2);
currentLocation = c.getString(3);
currUserName = c.getString(4);
currPassword = c.getString(5);
currStatID = currentStatIDstr;
Handler networkLookupHandler = new Handler();
Runnable networkLookupRunnable = new Runnable() {
public void run() {
try {
currStatIP = InetAddress.getByName(currentStatIPstr).toString().split("/")[1];
} catch (UnknownHostException e) {
e.printStackTrace();
}
int portNumber = 0;
try {
portNumber = Integer.parseInt(currentPort);
} catch(NumberFormatException nfe) {
nfe.printStackTrace();
}
String userName = currUserName;
String passWord = currPassword;
String[] command = commandtosend;
Object[] controlCommands = new Object[]{
currStatID,
currStatIP, //InetAddress of String representing the IP address
portNumber, //int representation of the port number, taken from String
currentLocation,
userName,
passWord,
command
};
/*for(int i=0;i<controlCommands.length;i++){
Log.d("object work","controlCommands[" + i + "] is " + controlCommands[i]);
}*/
mainCommunicationThread(controlCommands);
}
};
networkLookupHandler.post(networkLookupRunnable);
}
太好了,耶!它奏效了!我不再遇到NetworkOnMainThreadException异常了。 哦...等等..是的,我还是遇到了。
上述代码在API 10、12、14甚至16模拟器中没有触发异常,但如果我将其加载到运行Jellybean 4.1.1的三星谷歌Galaxy Nexus上,就会导致NetworkOnMainThreadException崩溃。即使上面的代码被包装在runnable里面。
我完全不知道如何修复这个问题。
mainCommunicationThread()
调用的内容)。最奇怪的是,这在4.1模拟器上可以运行,但在我的4.1手机上却不行。 - Octoth0rpe