2016-07-10 87 views
-1

我一直在閱讀關於AsyncTasks的大量內容,但我無法弄清楚什麼。我有一個AsyncTask,我開始用它來處理來自我的數據庫的請求的HttpURLConnection。數據庫工作是在doInBackground()中完成的,我有一個ProgressDialog在UI線程上運行,只顯示它正在加載。一旦doInBackground()完成,我的代碼會繼續執行,即使我在onPostExecute()中有一些事情需要在代碼繼續之前發生。等待AsyncTask完成其onPostExecute(),同時保持UI線程對ProgressDialog打開

有沒有辦法讓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

您的描述有點不清楚,只是不執行不管代碼是否需要等待,直到完成'onPostExecute()'所需的操作。 –

+0

在'onPostExecute()'中,關閉'ProgressDialog',如果登錄成功,則關閉'AlertDialog'。我真的沒有看到問題出在哪裏。 –

+0

@MikeM。我想我只是沒有看到我會如何解決AlertDialog的問題。 – saboehnke

回答

0

This post舉例爲了在調用onPostExecute()時有一個函數調用,以便可以從我需要訪問它的地方訪問AlertDialog。

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. 
    } 
} 

}

+0

請參閱我的編輯 – saboehnke

+0

你可以請張貼代碼。 –

+0

在post方法中使用alert.create()。cancel()來關閉警報對話框。 –

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. 
    } 
} 
} 
+0

請參閱我的編輯 – saboehnke

+0

loading.dismiss();是不正確的,你應該在UI線程中關閉你的對話框。 runOnUiThread(new Runnable(){ public void run(){ loading.dismiss(); } }); –

+0

loading.dismiss();在AsyncTake的onPostExecute()函數中調用。該函數在UI線程上運行。 – saboehnke

0

如果我理解正確的話,你有兩個對話(進步和警報),你要解僱他們中的一個,你得到後登錄響應,並保留另一個,直到數據庫工作完成。

如果是,我認爲您需要兩個異步任務,一個用於登錄,一個用於數據庫工作。關閉postExecute中的一個對話框(第一個異步任務的第一個對話框,並從第一個異步任務的postExecute中調用數據庫異步任務,然後在完成第二個異步任務時關閉第二個異步任務。