我一直在阅读有关AsyncTasks的大量信息,但我无法解决问题。我有一个AsyncTask我开始用于HttpURLConnection来处理来自我的数据库的请求。数据库工作在doInBackground()中完成,我有一个在UI线程上运行的ProgressDialog,它只显示它正在加载。一旦doInBackground()完成,我的代码就会继续,即使我在onPostExecute()中有一些东西需要在代码可以继续之前发生。
有没有办法让AsyncTask保持异步,所以我可以同时运行ProgressDialog并在doInBackgroun()中运行数据库,并等待它继续,直到调用了onPostExecute()?
澄清:
我不能只在onPostExecute()调用中调用一个函数。在启动时,会打开AlertDialog,以便用户输入用户名和密码,以便他们登录。当他们登录时,运行AsyncTask。我需要AlertDialog知道onPostExecute()何时完成才能关闭它。否则我会被困住。
以下是AlertDialog的代码:
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setCancelable(false);
final EditText usernameInput = new EditText(context);
usernameInput.setHint("Username");
final EditText passwordInput = new EditText(context);
passwordInput.setHint("Password");
passwordInput.setTransformationMethod(PasswordTransformationMethod.getInstance());
LinearLayout layout = new LinearLayout(context);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(usernameInput);
layout.addView(passwordInput);
alert.setView(layout);
alert.setTitle("Login");
alert.setPositiveButton("Login", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
String username = usernameInput.getText().toString();
String password = passwordInput.getText().toString();
if (username != "" && password != "")
{
Database database = new Database(currActivity);
database.Login(username, password);
if (database.IsLoggedIn())
{
SharedPreferences prefs = currActivity.getSharedPreferences("Preferences", currActivity.MODE_PRIVATE);
prefs.edit().putBoolean("Logged In", true).commit();
dialog.cancel();
}
else ShowLoginAlert(context);
}
}
});
alert.show();
以下是我的登录代码:
public void Login(String username, String password)
{
try
{
new AsyncLogin().execute(username, password).get();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (ExecutionException e1)
{
e1.printStackTrace();
}
}
private class AsyncLogin extends AsyncTask<String, String, String>
{
private static final int READ_TIMEOUT = 1000000;
private static final int CONNECTION_TIMEOUT = 1000000;
private URL url = null;
private HttpURLConnection conn = null;
ProgressDialog loading = new ProgressDialog(currActivity);
@Override
protected void onPreExecute()
{
super.onPreExecute();
loading.setMessage("\tLoading...");
loading.setCancelable(false);
loading.show();
}
@Override
protected String doInBackground(String... params)
{
try
{
url = new URL("http://mysite/myscript.php");
}
catch (MalformedURLException e)
{
e.printStackTrace();
return "Malformed URL Exception.";
}
try
{
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("username", params[0])
.appendQueryParameter("password", params[1]);
String query = builder.build().getEncodedQuery();
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
conn.connect();
}
catch (IOException e1)
{
e1.printStackTrace();
return "Connection Exception.";
}
try
{
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK)
{
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null)
{
result.append(line);
}
return result.toString();
}
else return "Unsuccessful data retrieval.";
}
catch (IOException e2)
{
e2.printStackTrace();
return "Response Exception.";
}
finally
{
conn.disconnect();
}
}
@Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
loading.dismiss();
if (result.equalsIgnoreCase("true"))
{
// Successfully logged in
SetIsLoggedIn(true);
Toast.makeText(currActivity, "Successfully logged in.", Toast.LENGTH_LONG).show();
}
else
{
// Incorrect credentials
SetIsLoggedIn(false);
Toast.makeText(currActivity, "Incorrect credentials.", Toast.LENGTH_LONG).show();
}
}
}
答案 0 :(得分:0)
您可以通过以下方式执行此操作:
class main extends Activity {
class Something extends AsyncTask<String, Integer, String> {
protected void onPreExecute() {
// showProgressDialog
}
protected String doInBackground(String... params) {
// Do your heavy stuff...
return null;
}
protected void onPostExecute(String result) {
// close your progress dialog and than call method which has
// code you are wishing to execute after AsyncTask.
}
}
}
答案 1 :(得分:0)
我认为你想要的并不是很困难,你可以使用以下代码:
class main extends MainActivity {
class SampleAsyncTask extends AsyncTask<String, Integer, String> {
protected void onPreExecute() {
// ProgressDialog
}
protected String doInBackground(String... params) {
// Do your database code...
return null;
}
protected void onPostExecute(String result) {
// close progress dialog
// code you are wishing to execute after AsyncTask.
}
}
}
答案 2 :(得分:0)
如果我理解正确,你有两个对话框(进度和警报),你想在获得登录响应后解除其中一个,并保持另一个直到数据库工作完成。
如果是,我认为你需要两个异步任务,一个用于登录,一个用于数据库工作。关闭postExecute中的一个对话框(第一个异步任务为0,从第一个异步任务的postExecute调用数据库异步任务,然后在第二个异步任务完成时关闭第二个。
答案 3 :(得分:0)
This post给出了一个使用接口的示例,以便在调用onPostExecute()时调用一个函数,以便可以从我需要访问它的位置访问AlertDialog。