2016-05-10 3 views
1

自分のサーバーからの送受信を処理するAsyncTaskクラスを作成しました。私がしようとしているのは、データを受け取ったときにイベントまたはコールバックを起動して、そのデータを使用してUIを操作できるようにすることです。AsyncTaskを使用したコールバック関数の作成

AsyncTaskクラス:

public class DataCollectClass extends AsyncTask<Object, Void, JSONObject> { 
    private JSONObject collected; 

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

    //@Override -Commented out because it doesn't like the override 
    protected void onPostExecute() { 
     try { 
      Log.d("Net", this.collected.getString("message")); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    protected JSONObject doInBackground(Object... params) { 
     OkHttpClient client = new OkHttpClient(); 

     // Get Parameters // 
     String requestURI = (String) params[0]; 
     RequestBody formParameters = (RequestBody) params[1]; 
     Request request = new Request.Builder().url(requestURI).post(formParameters).build(); 

     client.newCall(request).enqueue(new Callback() { 
      @Override 
      public void onFailure(Call call, IOException e) { 
       // DO something on FAIL 
      } 

      @Override 
      public void onResponse(Call call, Response response) throws IOException { 
       String jsonResponse = response.body().string(); 
       Log.d("Net", jsonResponse); 
       try { 
        DataCollectClass.this.collected = new JSONObject(jsonResponse); 
        Log.d("Net", DataCollectClass.this.collected.getString("message")); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 

     return collected; 
    } 
} 

これが働いている、それがログにJSONの期待される行を出力します。

それは次のようにActivityから呼ばれています:

new DataCollectClass().execute(requestURI, formVars); 

私はすべての上に見てきた、と私は、コールバックを追加する方法(どこ)​​に決定的な答えを見つけるように見えることはできません。好ましくは、コールバックコード自体はDataCollectClassでなければならないので、関連するコードはすべて同じ場所で再利用可能です。

プログラムが聴くことができるカスタムイベント発生(Javascriptライブラリに類似)を作成する方法はありますか?

私はこれで私の髪を引っ張ってきました!

UPDATE:

AsyncTaskが冗長であるので、私はそれを削除し、コードを書き直しました(場合には他の誰かがこの同じ問題を持っている):

パブリッククラスDataCollectClass { プライベートJSONObjectを収集。

public interface OnDataCollectedCallback { 
     void onDataCollected(JSONObject data); 
    } 

    private OnDataCollectedCallback mCallback; 

    public DataCollectClass(OnDataCollectedCallback callback, String requestURI, RequestBody formParameters){ 
     mCallback = callback; 
     this.collect(requestURI, formParameters); 
    } 

    public JSONObject collect(String requestURI, RequestBody formParameters) { 
     OkHttpClient client = new OkHttpClient(); 

     Request request = new Request.Builder().url(requestURI).post(formParameters).build(); 

     client.newCall(request).enqueue(new Callback() { 
      @Override 
      public void onFailure(Call call, IOException e) { 
       //TODO Add what happens when shit fucks up... 
      } 

      @Override 
      public void onResponse(Call call, Response response) throws IOException { 
       String jsonResponse = response.body().string(); 
       Log.d("Net", jsonResponse); 
       try { 
        DataCollectClass.this.collected = new JSONObject(jsonResponse); 

        if(mCallback != null) 
         mCallback.onDataCollected(DataCollectClass.this.collected); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
     return collected; 
    } 
} 
Activityから呼び出され

new DataCollectClass(new DataCollectClass.OnDataCollectedCallback() { 
    @Override 
    public void onDataCollected(JSONObject data) { 
     if(data != null) { 
      try { 
       // Do Something // 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
}, requestURI, formVars); 

すべて完璧に働いて! ありがとう!

+0

OkHttpを使用している場合、AsyncTaskは必要ありません。 [Asynchronous get in OkHttp](https://github.com/square/okhttp/wiki/Recipes#asynchronous-get) –

+0

AsyncTasksを削除したい場合、VolleyまたはRetrofitはJSONの操作に適していますデータ。 –

答えて

1

AsyncTaskのコールバックを利用する場合は、次のように処理できます。

魔法が

new DataCollectClass(new OnDataCollectedCallback() { 
     @Override 
     public void onDataCollected(JSONObject data) { 
      if(data != null) 
       // DO something with your data 
     } 
    }).execute(requestURI, formVars); 

を実現するために続いて、この(以下であるものを追加するようにコードを修正する)

public class DataCollectClass extends AsyncTask<Object, Void, JSONObject> { 

    public interface OnDataCollectedCallback{ 
     void onDataCollected(JSONObject data); 
    } 

    private OnDataCollectedCallback mCallback; 

    public DataCollectClass(OnDataCollectedCallback callback){ 
     mCallback = callback; 
    } 

    // your code that is already there 
    ... 

    @Override 
    public onPostExecute(JSONObject response){ 
     if(mCallback != null) 
      mCallback.onDataCollected(response); 
    } 
} 

ような何かをしかし、それは、most networking libraries, including OkHttp, handle background threads internally, and include callbacks to utilize with the requests.

注目に値しますこれはカスタムインターフェイスも実装しているので、AsyncTaskにどのように使用できるかを他の人が見ることができます。

+0

これを再度確認してください。 'DataCollectClass.this.collected'はアクティビティ内では動作しません。 –

+0

@ cricket_007私はちょうど彼のコードをコピーしています:PIはそれを修正します – zgc7009

+1

ええ、私もそうです:)私はOPと思っています.OnHttpを使ったAsyncTaskの必要性と競合している場合は、 –

1

asynchronous get in OkHttpがありますので、AsyncTaskは必要ありませんが、学習の練習として、コールバックをパラメータとして定義することができます。

new DataCollectClass(new Callback() { 
      @Override 
      public void onFailure(Call call, IOException e) { 
       // DO something on FAIL 
      } 

      @Override 
      public void onResponse(Call call, Response response) throws IOException { 
       JSONObject collected = null; 
       String jsonResponse = response.body().string(); 
       Log.d("Callback - Net", jsonResponse); 
       try { 
        collected = new JSONObject(jsonResponse); 
        Log.d("Callback - Net", collected.getString("message")); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
     }).execute(requestURI, formVars); 

asynctaskを使ってAsyncTask

public class DataCollectClass extends AsyncTask<Object, Void, Call> { 
    private Callback mCallback; 
    private OkHttpClient client; 

    public DataCollectClass(Callback callback) { 
     this.mCallback = callback; 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     this.client = new OkHttpClient(); 
    } 

    @Override 
    protected void onPostExecute(Call response) { 
     if (response != null && this.mCallback != null) { 
      response.enqueue(this.mCallback); 
     } 
    } 

    @Override 
    protected Call doInBackground(Object... params) { 

     // Get Parameters // 
     String requestURI = (String) params[0]; 
     RequestBody formParameters = (RequestBody) params[1]; 
     Request request = new Request.Builder().url(requestURI).post(formParameters).build(); 

     return client.newCall(request); // returns to onPostExecute 
    } 
} 
+0

この回答はこの特定の質問に適しています。提供されたコールバックを適切に使用する方法を示します。 – zgc7009

0

コールWebサービスは、昔ながらのです。あなたは、ボレーを使用したり、改造することができます。 しかし、このプロセスを使用してWebサービスを呼び出すことができます。/

クラスDownloadableAsyncTaskを作成断片

public interface IAsynchronousTask { 
     public void showProgressBar(); 
     public void hideProgressBar(); 
     public Object doInBackground(); 
     public void processDataAfterDownload(Object data); 
} 

  1. はインターフェイスを作成し、あなたの活動でそれを実装します。ここでの手順です。このクラスは次のとおりです。

    import android.os.AsyncTask; 
    import android.util.Log; 
    
    public class DownloadableAsyncTask extends AsyncTask<Void, Void, Object> { 
    
        IAsynchronousTask asynchronousTask; 
    
        public DownloadableAsyncTask(IAsynchronousTask activity) { 
         this.asynchronousTask = activity; 
        } 
    
        @Override 
        protected void onPreExecute() { 
         if (asynchronousTask != null) 
          asynchronousTask.showProgressBar(); 
        } 
    
        @Override 
        protected Object doInBackground(Void... params) { 
         try { 
          if (asynchronousTask != null) { 
           return asynchronousTask.doInBackground(); 
          } 
         } catch (Exception ex) { 
          Log.d("BSS", ex.getMessage()==null?"":ex.getMessage()); 
         } 
         return null; 
        } 
    
        @Override 
        protected void onPostExecute(Object result) { 
         if (asynchronousTask != null) { 
          asynchronousTask.hideProgressBar(); 
          asynchronousTask.processDataAfterDownload(result); 
         } 
        } 
    
    } 
    

    あなたのアクティビティには、このメソッドがあります。

    DownloadableAsyncTask downloadAsyncTask; 
    ProgressDialog dialog; 
        private void loadInformation() { 
          if (downloadAsyncTask != null) 
           downloadAsyncTask.cancel(true); 
          downloadAsyncTask = new DownloadableAsyncTask(this); 
          downloadAsyncTask.execute(); 
    
         } 
    
         @Override 
         public void showProgressBar() { 
          dialog = new ProgressDialog(this, ProgressDialog.THEME_HOLO_LIGHT); 
          dialog.setMessage(" Plaese wait..."); 
          dialog.setCancelable(false); 
          dialog.show(); 
    
         } 
    
         @Override 
         public void hideProgressBar() { 
          dialog.dismiss(); 
    
         } 
    
         @Override 
         public Object doInBackground() { 
          // Call your Web service and return value 
    
         } 
    
         @Override 
         public void processDataAfterDownload(Object data) { 
          if (data != null) { 
           // data is here 
          }else{ 
           //"Internal Server Error!!!" 
          } 
    
         } 
    
    今だけ、あなたはprocessDataAfterDownload()にあなたの応答を取得しますloadInformation()メソッドを呼び出します。

関連する問題