问题
I have a button, which on pressed, executes the following code:
public void onClick(View v) {
// TODO Auto-generated method stub
//progressSpin.setVisibility(View.VISIBLE);
try {
data=new WebkioskExtractor().execute(username,password).get();
System.out.println("Data = "+data);
} catch (Exception e) {
// TODO Auto-geneorated catch block
e.printStackTrace();
}
//progressSpin.setVisibility(View.GONE);
}
as clear from the code, i have to wait for the AsyncTask to finish because i am relying on the data it returns. the problem is that while the task in being executed (it fetches some data from the internet) the button remains in the pressed state. even if i set the progressbar i created to VISIBLE, it does not show up.
How can i fix this? I would like the button to be pressed once and then the progressbar should start spinning, which isn't happening.
回答1:
Don't use get()
.
data=new WebkioskExtractor().execute(username,password).get(); // Bad! :(
data=new WebkioskExtractor().execute(username,password); // Good! :)
It blocks the UI
which is why your Button
remains pressed. This is also why your ProgressBar
isn't showing up (it also runs on the UI
). I assume you start your ProgressBar
in onPreExecute()
and dismiss()
it in onPostExecute()
of your AsyncTask
. If not, this is what you should be doing. If everything else in your AsyncTask
is set up correctly then removing .get()
should fix your problem.
Return your result from doInBackground()
to onPostExecute()
and this should give you what you want. You can also do whatever you need to on the UI
from onPostExecute()
or any other method of the AsyncTask
besides doInBackground()
.
ProgressBar
You don't need to set the Visibility
on the ProgressBar
. See this example:
public class GetUsersTask extends AsyncTask<Void, Void, Void> {
ProgressDialog progress = ProgressDialog.show(LoginScreen.this, "Downloading Users", "Please wait while users are downloaded");
// you can create it here
@Override
protected void onPreExecute()
{
// show it here like so
progress.setCancelable(false);
progress.isIndeterminate();
progress.show();
}
@Override
protected void onPostExecute(Void result) {
// and dismiss it here
progress.dismiss();
}
}
@Override
protected void onProgressUpdate(Void... values) {
// can update the ProgressBar here if you need to
}
@Override
protected Void doInBackground(Void... params) {
...
}
Using a callback
If you need to get a result from AsyncTask
which is not an inner-class of your Activity then you can use an interface
with a callBack
. More about doing that in this answer
AsyncTask Docs
来源:https://stackoverflow.com/questions/17425807/button-remains-pressed-while-the-asynctask-is-being-executed