Java 如何使用后台线程检查套接字是否已连接
我正在开发一个应用程序,在这个应用程序中,我在读写套接字之前检查端口的可用性。我使用以下代码检查状态Java 如何使用后台线程检查套接字是否已连接,java,android,sockets,Java,Android,Sockets,我正在开发一个应用程序,在这个应用程序中,我在读写套接字之前检查端口的可用性。我使用以下代码检查状态 private boolean isAvailable(String host, int port) { try { Socket socket = new Socket(); socket.connect(new InetSocketAddress(host, port), 1000); isPortAva
private boolean isAvailable(String host, int port) {
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(host, port), 1000);
isPortAvailable = socket.isConnected();
} catch (IOException e) {
isPortAvailable = false;
}
return isPortAvailable;
}
在此之后,我将在onClick()上检查此状态
但我的问题是,如果我在主线程上检查此状态,那么android将给我networkonMainThradException
那么我如何使用后台线程管理此操作?如下所示:
private class CheckAvailabilityTask extends AsyncTask<Void, Void, Boolean> {
String ip;
int port;
public CheckAvailabilityTask(String ip, int port) {
this.ip = ip;
this.port = port;
}
@Override
protected Boolean doInBackground(Void... params) {
return isAvailable(this.ip, this.port);
}
@Override
protected void onPostExecute(Boolean isAvailable) {
if (iisAvailable) {
startActivity(new Intent(getApplicationContext(),ActivityLivingRoom.class));
} else
Toast.makeText(getApplicationContext(),"Connection Error !", Toast.LENGTH_SHORT).show();
}
}
我认为最好的解决方案是,在click事件上启动一个新线程,并将启动活动代码放在同一个线程中
如果您使用的是toast,您可以从该线程执行,但如果您计划更新UI(如红色/绿色状态),则必须使用处理程序和消息
仅供参考,Asynctask只是删除了线程的实现,并向人们展示了一个很好的抽象 试试这个
private class SocketCheckTask extends AsyncTask<String , Integer , Boolean> {
String classname="";
public SocketCheckTask (String classname) {
this.classname=classname;
}
@Override
protected Boolean doInBackground(String... params) {
return isAvailable(params[0], Integer.parseInt(params[1]);
}
@Override
protected void onPostExecute(Boolean isAvailable) {
if (isAvailable)) {
Class c=Class.forName("yourpackage"+classname);
startActivity(new Intent(getApplicationContext(),c));
} else
Toast.makeText(getApplicationContext(),"Connection Error !", Toast.LENGTH_SHORT).show();
}
}
您不能仅仅为了确定主机:端口是否可用而打开或关闭套接字
测试是否有任何服务或资源可用的唯一真正方法是尝试使用它
只需在需要时执行连接和I/O,并在此时处理产生的异常。无论如何,你必须抓住他们
不要编写试图预测未来的代码。你不能使用AsyncTask或单独的线程吗?@Pragnani,我如何像使用返回布尔值的方法一样使用AsyncTask?获取一个布尔字段,并为其分配一个由doinBackground中的IsAvailable方法返回的值。这有什么错。。让我知道。?@Pragnani但在每次点击按钮时,我都以该方法传递不同的IP,我如何使用AsynckTask管理此问题?请检查我的答案……应该是这样的work@Thanks但是我想对多个按钮进行检查,那么在这个任务中我应该在哪里传递我的ip呢?这个类给了我类似于的错误,返回类型与AsyncTask不兼容
检查我的更新答案,doInbackground应该返回Boolean,在返回字符串之前,Hanks,但我仍然对一件事感到困惑,我不想每次打开ActivityLivingRoom.class
activity,这也应该改变你这是什么意思?您可以创建一个单独的类CheckAvailabilityTask,并从任何其他活动调用它requireds@Waqas他可能希望asynctask作为单独的类,而不是内部类class@thanks但我仍然对一件事感到困惑,因为ip chages启动活动也会发生变化,我不想每次打开ActivityLivingRoom.class
activity我如何从AsynkTask的postExecute()
方法调用startActivity()
方法?@juned为什么你认为你不能。。?我已经在答案检查中给出了我的意思是,如果我使用单独的AsynkTask
classAsyctask是为更新UI而设计的,我看不到你在任何地方更新UI。但你肯定可以使用Asynctask。事实上,我想在开始执行套接字i/O的活动之前检查连接是否可用。这正是我刚才告诉你不要做的。您应该做的是(a)尝试连接和(b)尝试读取或写入。没有“连接可用”这样的概念。你的代码实际上是创建一个套接字,然后扔掉它。这没有任何意义。我明白你的意思了,谢谢,但我还是想知道有没有其他方法可以知道插座是打开的还是关闭的?@juned这个问题模棱两可。如果Socket.isClosed()
返回false,则套接字打开。这会告诉你是否曾经关闭过插座。然而,这个套接字和对等方的套接字之间的连接可以处于任何状态,在TCP中,您可以找到的唯一方法是向它写入或从中读取。这里没有API。@downvoter欢迎您的评论:但是,您无法解释的downvote并不比单纯的站点破坏好多少。如果你对答案有不同意见,那就说出来吧。
new CheckAvailabilityTask(IP, PORT).execute();
private class SocketCheckTask extends AsyncTask<String , Integer , Boolean> {
String classname="";
public SocketCheckTask (String classname) {
this.classname=classname;
}
@Override
protected Boolean doInBackground(String... params) {
return isAvailable(params[0], Integer.parseInt(params[1]);
}
@Override
protected void onPostExecute(Boolean isAvailable) {
if (isAvailable)) {
Class c=Class.forName("yourpackage"+classname);
startActivity(new Intent(getApplicationContext(),c));
} else
Toast.makeText(getApplicationContext(),"Connection Error !", Toast.LENGTH_SHORT).show();
}
}
SocketCheckTask task=new SocketCheckTask ("ActivityLivingRoom");
task.execute(ipadress,port);