gpt4 book ai didi

java - AsyncTask 不会在第一次尝试时调用 OnCancel()

转载 作者:行者123 更新时间:2023-11-30 01:23:53 25 4
gpt4 key购买 nike

我在 Android Studio 中使用 AsyncTask 在后台使用 TCP 连接。然后我在 PreExecute 中有一个运行器,它以 5 秒的超时时间执行一个运行器,然后在 AsyncTask 上调用 cancel(true)(因为 DataOutputStream 没有超时覆盖)。

问题是,当我第一次打开我的应用程序进行测试并尝试登录时,它只到达“联系服务器”。永远不会调用消息“TCP 超时”。如果我再次尝试登录,它会正常工作。但从来没有第一次。所以我猜 cancel(true) 永远不会被调用。我尝试在 PreExecuteonLoginButtonClicked 代码后面执行超时运行程序(这是一件愚蠢的事情),但没有成功。

我做错了什么?

 private class AsynchronisedTask extends AsyncTask<String, Void, String> {

@Override
protected String doInBackground(String... strings) {
String serverAnswer = "";
if (!isCancelled())
serverAnswer = new TCP().SendToServer(strings[0]);
return serverAnswer;
}

@Override
protected void onPostExecute(String result) {
if (result.contains("Accepted")) {
Toast.makeText(LoginActivity.this, "Logged in.", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(LoginActivity.this, ProfilePageActivity.class);
Profile profile = new Profile();
profile.setProfileName(usernameText.getText().toString());
intent.putExtra("Username", usernameText.getText().toString());
startActivity(intent);
} else {
Toast.makeText(LoginActivity.this, "Invalid username or password.", Toast.LENGTH_SHORT).show();
}
}

@Override
protected void onPreExecute() {
handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (asynchronisedTask.getStatus() == AsyncTask.Status.RUNNING) {
asynchronisedTask.cancel(true);
}
}
}, 5000);
Toast.makeText(LoginActivity.this, "Contacting server.", Toast.LENGTH_SHORT).show();
}

@Override
protected void onCancelled(String result) {
Toast.makeText(LoginActivity.this, "TCP Timeout.", Toast.LENGTH_SHORT).show();
}
}



public class TCP implements ITCP {
private String IP = "192.168.1.33"; // LOCAL "192.168.1.33" PUBLIC **.***.***.***
private int PORT = 9000;

@Override
public String SendToServer(String stringToServer) {
String answer = "";
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;

try {
socket = new Socket(IP, PORT);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF(stringToServer);
answer = dataInputStream.readUTF();

} catch (UnknownHostException e) {
e.printStackTrace();

} catch (IOException e) {
e.printStackTrace();

} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (answer instanceof String)
return answer;
else return answer.toString();
}

最佳答案

直到 doInBackground 完成后才会调用 OnCancelled。由于 doInBackground 在尝试进行 TCP 数据传输时卡住了,所以这种情况永远不会发生。

我实际上从未见过 onCanceled 被使用过。但它唯一应该做的就是清理 UI。结束任务的方法是让 doInBackground 定期检查 isCanceled() 并在其为真时自行终止。请记住,在任何语言中都没有办法安全地终止通用线程,除非让线程本身确定这样做是安全的。所以取消不只是取消任务,它只是设置一个标志供其他线程检查。

如果您调用 task.cancel(true),套接字将被中断导致 InterruptedException,您可以捕获它并允许任务自行取消。

关于java - AsyncTask 不会在第一次尝试时调用 OnCancel(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36715659/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com