2017-01-19 10 views
1

Webサービスにアクセスするアプリケーションを作成しています.JSONを使用してオブジェクトを作成し、コード内で使用します。私のアプリが動作しているにもかかわらず、私はそれがよく書かれており、完璧であることを知らない。AsyncTaskクラスの正しい方法が、別のAsyncTaskクラスがプロセスを終了するのを待つ方法

サンプルコードをデモするためのサンプルコードを説明します。まず、EditTextとButtonを使用してアクティビティを作成しました。ここでユーザーはコードを入力し、ボタンをクリックしてデータベースが存在するかどうかを確認します。メインはここにあります:私のbutton.OnClickListenerで私はEditTextに何かがあるかどうかを確認し、インターネットに接続している場合は< - (私はこれに関して何の問題も抱えていませんでした)、その後はRestClientクラスを呼び出しますAsyncTaskは、バックグラウンドでWebServiceにアクセスし、そこからオブジェクトを取得します。そしての後にこれが私はこのRestClientから結果を得るでしょう。私の解決策は、RestClientを待ってから新しいAsyncTaskを開始し、そのプロセスを開始してオブジェクトを取得することでした。

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後に実行され、ここで

が私のWebサービスから汎用オブジェクトを返す私の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のみ最初AsyncTask

何か

public interface AsyncFinishedCallback{ 
    public void onAsyncFinished(); 
} 

等により解雇 onPostExecute後最初の 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

'新しいAsyncFinishedCallback()'はコンストラクタ内にあるべきではありませんか? – Cocholate

+0

RestClientのカウンターストラクターにあります。あなたの右 – Ekalips

0

これを試してみてください:uは最初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 
      } 
     } 
    } 
} 
関連する問題