AsyncTask没有足够快地向主线程返回结果
我有一个asynctask
,它从oracle数据库中获取了userPin.在我的主线程中,然后在按钮上运行asynctask
.数据库中的值分配给名为userPinRetrieved
的变量.
I have an asynctask
that is getting a userPin from my oracle database. In my Main thread then on a button I am running the asynctask
. The value from the database is assigned to a variable called userPinRetrieved
.
当我调试此变量时,它接收到正确的值.但是,当我正常运行该应用程序时,它会收到null.经过一些研究并使用Thread.Sleep(x)
之后,我可以看到这是由于asynctask没有及时将结果返回给主线程和变量.
When I debug this variable it is receiving the correct value. However, when I am running the app normally it is receiving null. After doing some research and using Thread.Sleep(x)
I can see that is due to the fact that the asynctask is not returning the result to the main thread and the variable in time.
已建议我不要使用Thread.Sleep(x)
,我有什么选择?
I have been advised not to use Thread.Sleep(x)
, what alternatives do I have?
这是我的代码:
AsyncTask:
AsyncTask:
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
方法中处理异步任务的结果.
The point of AsyncTask
is to move the processing to another thread because you don't know how much time it will take to run a certain task. You can process the result of the async task inside the onPostExecute
method.
因此将结果的用法移到那里:
So move the usage of the result to there:
@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();
}
}
您还可以定义在处理完成时将被调用的方法:
You can also define a method that will be called when the processing is finished:
protected void onPostExecute(String userPinRetrieved) {
processValue(userPinRetrieved);
}
在AsyncTask中从活动中引用变量时,请务必小心,如果活动在处理AsyncTask时被破坏,则可能导致内存泄漏.
You need to be careful when referencing variables from your activity in the AsyncTask, if the activity gets destroyed during the processing of your AsyncTask it can cause a memory leak.