针对(一)中写的pingThread和keeperThread,pingThread是ping的工作线程,keeperThread是ping的守护线程,防止ping在执行过程中卡死用的。
private class PingThread extends Thread{
private Process process;
@Override
public void run() {
super.run();
boolean isRun =true;
do{
String ipaddr_str=ipaddr_etxt.getText().toString();
String line =null;
BufferedReader successReader =null;
String command = "ping " + ipaddr_str;
Bundle bundle = new Bundle();
try {
process = Runtime.getRuntime().exec(command);
if (process == null) {
bundle.putString(pingRes, failPingStr);
Message msg = new Message();
msg.what = msgKey1;
msg.setData(bundle);
mHandler.sendMessage(msg);
}else
{
successReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = successReader.readLine()) != null) {
pingIsAlive =true;
bundle.putString(pingRes, line);
Message msg = new Message();
msg.what = msgKey1;
msg.setData(bundle);
mHandler.sendMessage(msg);
}
bundle.putString(pingRes, cannotReachStr);
Message msg = new Message();
msg.what = msgKey1;
msg.setData(bundle);
mHandler.sendMessage(msg);
}
}catch (IOException e) {
bundle.putString(pingRes, failPingStr);
Message msg = new Message();
msg.what = msgKey1;
msg.setData(bundle);
mHandler.sendMessage(msg);
}
isRun =false;
}while (isRun);
}
@Override
public void interrupt() {
super.interrupt();
if(process != null)
{
process.destroy();
Bundle bundle = new Bundle();
if(pingIsAlive)
bundle.putString(pingRes, finishPingStr);
else
bundle.putString(pingRes, timeOutStr);
Message msg = new Message();
msg.what = msgKey1;
msg.setData(bundle);
mHandler.sendMessage(msg);
}
pingIsAlive =false;
}
}
在pingThread中,run()方法是工作的方法,process = Runtime.getRuntime().exec(command)是实际工作的方法,通过命令行,来完成ping的命令,然后process.getInputStream()来得到ping的输出。其中pingThread并不能直接设置android view的显示,需要通过Message传递到主线程中进行显示,传递的数据通过bundle类来传递,bundle类是一个key-value的典型的消息结构。
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle bundle;
switch (msg.what){
case msgKey1:
bundle =msg.getData();
show_txt.setText(bundle.getString(pingRes));
break;
default:
break;
}
}
};
message的handler类来处理消息,这个app就一种消息,即ping之后的结果,结果显示在主view的show_txt上。
private class KeeperThread extends Thread {
@Override
public void run() {
super.run();
while (true)
{
if(pingIsAlive)
{
pingIsAlive =false;
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else
{
if (pingThread.isAlive())
{
pingThread.interrupt();
}
break;
}
}
}
}
由于ping的过程中,有可能会发生阻塞,所以需要个keeperThread来监控pingThread是否正在运行,每5秒监控一下pingIsAlive变量是否被pingThread置位,如果没有被pingThread置位,则直接中断pingThread,并发送message来报告结果超时。