2017-01-19 3 views
1

Я делаю приложение, которое обращается к веб-службе и с помощью JSON, которую я получаю от него. Я создаю объект и использую его в своем коде. , Хотя мое приложение работает, я не знаю, что он хорошо написан и безупречен.Как правильный способ класса AsyncTask ждать, пока другой класс AsyncTask завершит свои процессы

Я объясню, что у меня тогда было показано несколько примеров кода. Прежде всего, я создал Activity с EditText и Button, где пользователь вводит код и нажимает кнопку, чтобы получить доступ к моему базу данных и проверить, существует ли она. Главное здесь: В моей button.OnClickListener я проверяю, есть ли в EditText что-то на нем, и если у меня есть подключение к Интернету < - (у меня никогда не было никаких проблем), а после этого я вызываю свой класс RestClient, который расширен с AsyncTask, которые получают доступ к WebService в фоновом режиме и получают от него объект. И только после это я получу результат из этого RestClient. Мое решение состояло в том, чтобы запустить новую AsyncTask, которая ждет моего RestClient, а затем запустит процесс для получения объекта.

здесь образец моего кода моей restClient возвращающие Generic Object из моего веб-сервиса:

public class RestClient<t> extends AsyncTask<String, String, String> { 

private Class<t> tClass; 
private t ObjReturn; 

public RestClient(Class<t> tClass) 
{ 
    this.tClass = tClass; 
} 

public Object getObjectResponse(){ 
    return ObjetoDeRetorno; 
} 

@Override 
protected void onPreExecute() { 
    super.onPreExecute(); 
} 

@Override 
protected String doInBackground(String... OnlyTheURL) { 
    String urlString = OnlyTheURL[0]; 
    String error = null; 
    WebApiDeRetorno = new WebApiRetorno(); 
    try { 
     Log.i("RestClient","Starting connection"); 

     URL url = new URL(urlString); 
     HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
     connection.setRequestMethod("GET"); 

     connection.connect(); 

     String result = convertStreamToString(connection.getInputStream()); 

     connection.disconnect(); 

     JSONObject jsonObject = new JSONObject(result); 

     String obj = jsonObject.get("returnObject").toString(); 

     Gson gson = new Gson(); 
     ObjReturn = gson.fromJson(obj, tClass); 


    } catch (IOException | JSONException e) { 
     e.printStackTrace(); 
     return error; 
    } 
    return null; 
} 

@Override 
protected void onPostExecute(String s) { 
    super.onPostExecute(s); 
    } 
} 

мой днище функции:

buttonConfirmar.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 


      restClient = new RestClient<>(MyObject.class); 

      restClient.execute(getString(R.string.WebServiceURL)); 
      new WhenWebServiceConnectionFinished().execute(); 

     } 
    }); 

Другой AsyncTask класс, который выполняется ПОСЛЕ RestClient и Досрочное завершение:

private class WhenWebServiceConnectionFinished extends AsyncTask<String, Void, Boolean> { 
    @Override 
    protected void onPreExecute() { 
     progressDialog.show(); 
     super.onPreExecute(); 
    } 

    @Override 
    protected Boolean doInBackground(String... params) { 

     //THIS IS WHAT I DON'T KNOW IF IT'S OK TO DO: 
     do { 
      try { 
       Thread.sleep(10); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } while (restClient.getStatus() != AsyncTask.Status.FINISHED); 
     //WAITING THE restClient.getStatus CHANGE TO FINISHED WITH Thread.sleepS. 

     if (checkWebApiRetorno()) { 
      objectReturnFromWebApi = (MyObject) restClient.getObjectResponse(); 

      Intent intent = new Intent(thisActivity, NewActivity.class); 
      startActivity(intent); 
      finish(); 
      return true; 
     } 
     return false; 
    } 

    @Override 
    protected void onPostExecute(Boolean success) { 
     if (progressDialog.isShowing()) 
      progressDialog.dismiss(); 

     if (!success) 
      dialogBuilder.create().show(); 

     super.onPostExecute(success); 
    } 
} 

ответ

3

Добавить отзыв к первому AsyncTask и запустить второй только после onPostExecute выпущенных первого AsyncTask

Что-то вроде

public interface AsyncFinishedCallback{ 
    public void onAsyncFinished(); 
} 

и в первом AsyncTask сделать конструктор как этого

public RestClient(Class<t> tClass, AsyncFinishedCallback callback) 
{ 
    this.tClass = tClass; 
    this.callback = callback; //declare it somewhere as a field 
} 

и чем

@Override 
protected void onPostExecute(String s) { 
    super.onPostExecute(s); 
    if(callback!=null) 
     callback.onAsyncFinished(); 
    } 
} 

чем в функция кнопки

buttonConfirmar.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 


     restClient = new RestClient<>(MyObject.class, new AsyncFinishedCallback(){ 
    @Override 
    public void onAsyncFinished(){ 
      new WhenWebServiceConnectionFinished().execute(); 
    } 
}); 

     restClient.execute(getString(R.string.WebServiceURL)); 
+0

Это путь. – Alan

+0

'new AsyncFinishedCallback()' не должен находиться в конструкторе? – Cocholate

+0

Он находится в консультанте RestClient. Твое право – Ekalips

0

попробовать это: начать другую задачу, когда и получить результат от первого Async task использования AsyncTask<String, String, Boolean>

public class RestClient<t> extends AsyncTask<String, String, Boolean> { 

private Class<t> tClass; 
private t ObjReturn; 

public RestClient(Class<t> tClass) 
{ 
    this.tClass = tClass; 
} 

public Object getObjectResponse(){ 
    return ObjetoDeRetorno; 
} 

@Override 
protected void onPreExecute() { 
    super.onPreExecute(); 
} 

@Override 
protected Boolean doInBackground(String... OnlyTheURL) { 
    String urlString = OnlyTheURL[0]; 
    String error = null; 
    WebApiDeRetorno = new WebApiRetorno(); 
    try { 
     Log.i("RestClient","Starting connection"); 

     URL url = new URL(urlString); 
     HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
     connection.setRequestMethod("GET"); 

     connection.connect(); 

     String result = convertStreamToString(connection.getInputStream()); 

     connection.disconnect(); 

     JSONObject jsonObject = new JSONObject(result); 

     String obj = jsonObject.get("returnObject").toString(); 

     Gson gson = new Gson(); 
     ObjReturn = gson.fromJson(obj, tClass); 
     return true; 

    } catch (IOException | JSONException e) { 
     e.printStackTrace(); 
     return false;; 
    } 
    return true; 
} 

@Override 
protected void onPostExecute(Boolean result) { 
    if (result) { 
      //success occurs task finish 
      new WhenWebServiceConnectionFinished().execute(); 
     } else { 
       //error occurs 
      } 
     } 
    } 
} 
Смежные вопросы