2016-07-10 1 views
-1

AsyncTasks에 대한 좋은 양을 읽었지만 뭔가를 파악할 수 없습니다. 내 데이터베이스에서 요청에 대한 HttpURLConnection에 사용되는 시작 AsyncTask 있어요. 데이터베이스 작업은 doInBackground()에서 수행되며로드 중임을 나타내는 UI 스레드에서 실행되는 ProgressDialog가 있습니다. 그래도 doInBackground()가 완료되면 코드가 계속되기 전에 일어날 필요가있는 onPostExecute()에 몇 가지 사항이 있어도 코드가 계속됩니다.AsyncTask가 onPostExecute()를 완료하면서 ProgressDialog에 대한 UI 스레드를 열어 둘 때까지 기다립니다.

AsyncTask를 비동기로 유지하여 ProgressDialog를 실행할 수 있고 동시에 doInBackgroun()에서 데이터베이스 작업을 수행 할 수 있습니까? 또한 onPostExecute()가 호출 될 때까지 계속 대기 할 수 있습니까?

는 명확히하기 :

난 그냥 onPostExecute() 호출에서 함수를 호출 할 수 없습니다. 실행시 사용자가 로그인 할 수 있도록 사용자 이름과 비밀번호를 입력 할 수 있도록 AlertDialog가 열립니다. 그들이 login을 누르면 AsyncTask가 실행됩니다. onPostExecute()가 언제 완료되었는지 알기 위해 AlertDialog가 필요합니다. 그렇지 않으면 나는 그것에 매달릴 것이다.

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를 배치하는 방법으로 내가 어떻게 AlertDialog를 무시할 수 있는지 보지 못하고있는 것 같습니다. – saboehnke

답변

0

This post 예제를 제공합니다. onPostExecute()가 호출 될 때 호출되는 함수를 갖기 위해 인터페이스를 사용하는 것입니다.

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. 
    } 
} 
다음
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(); 

가 로그인 내 코드입니다 : 여기

은 처음에에 AlertDialog에 대한 코드입니다

}

+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 (첫 번째 비동기 작업 중 0 개를 닫고 첫 번째 비동기 작업의 postExecute에서 데이터베이스 비동기 작업을 호출 한 다음 두 번째 비동기 작업 완료시 두 번째 작업을 닫습니다.)

관련 문제