java - AsyncTask 没有足够快地将结果返回给主线程
问题描述
我有一个asynctask
从我的 oracle 数据库中获取 userPin 的设备。在我的主线程中,然后在一个按钮上我正在运行asynctask
. 数据库中的值被分配给一个名为 的变量userPinRetrieved
。
当我调试此变量时,它正在接收正确的值。但是,当我正常运行应用程序时,它会收到 null。在做了一些研究和使用之后,Thread.Sleep(x)
我可以看到这是由于 asynctask 没有及时将结果返回给主线程和变量。
我被建议不要使用Thread.Sleep(x)
,我有什么替代品?
这是我的代码:
异步任务:
String line;
BufferedReader br=new BufferedReader(new InputStreamReader(con.getInputStream()));
while ((line=br.readLine()) != null) {
JSONObject json = new JSONObject(line);
Log.d("Line",line);
if (json.getString("userPin") == null){
userPinRetrieved = "PIN NOT RECEIVED";
Log.d("userpin", userPinRetrieved);
} else {
userPinRetrieved = json.getString("userPin");
Log.d("userpin", userPinRetrieved);
}
}
}
} catch (Exception e) {
Log.v("ErrorAPP", e.toString());
}
return "";
}
@Override
protected void onPostExecute(String userPinRetrieved) {
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
}
登录按钮:
signIn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AsyncTaskRunner postReq = new AsyncTaskRunner();
postReq.execute("start");
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Toast.makeText(UserLogin.this, userPinRetrieved + " " + userPin, Toast.LENGTH_LONG).show();
if (userPin.equals(userPinRetrieved)) {
Toast.makeText(UserLogin.this, "Access Granted!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
Toast.makeText(UserLogin.this, "Hello " + employee, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(UserLogin.this, "Access Denied! Incorrect Pin", Toast.LENGTH_SHORT).show();
}
}
});
任何人都可以提供建议吗?
谢谢
解决方案
关键AsyncTask
是将处理移到另一个线程,因为您不知道运行某个任务需要多少时间。您可以在方法内处理异步任务的结果onPostExecute
。
所以将结果的用法移到那里:
@Override
protected void onPostExecute(String userPinRetrieved) {
if (userPin.equals(userPinRetrieved)) {
Toast.makeText(UserLogin.this, "Access Granted!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
Toast.makeText(UserLogin.this, "Hello " + employee, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(UserLogin.this, "Access Denied! Incorrect Pin", Toast.LENGTH_SHORT).show();
}
}
您还可以定义一个在处理完成时将调用的方法:
protected void onPostExecute(String userPinRetrieved) {
processValue(userPinRetrieved);
}
在 AsyncTask 中引用活动中的变量时需要小心,如果活动在处理 AsyncTask 期间被破坏,则可能导致内存泄漏。
推荐阅读
- reactjs - Problem with sorting for pagination in Meteor after viewing a document detail
- python - 从字符串输入中过滤元素
- c++ - I could not notice any difference in output, with and without using std::flush
- nodemcu - 我可以使用 PlatformIO 扩展在 VS Code 中创建 NodeMCU 项目吗?
- javascript - 严格模式禁止隐式创建全局属性“推断”
- linux - How to create deb that install another deb before installation?
- python - 在不使用 ajax 的情况下,根据之前在 Flask python 中的选择填充下拉菜单?
- django - How to remove all data about users from database from heroku server?
- javascript - AJAX 标头中的希伯来字符
- spring-boot - Get connectionexception when using RestHighLevelClient for Elastic search