AndroidのOkHttpパッケージ作成非同期HTTPリクエスト呼び出しの方法を詳しく理解する

3570 ワード

OkHttpは、通常の同期HTTPリクエストに加えて、非同期HTTPリクエスト呼び出しもサポートします.同期呼び出しを使用すると、HTTPリクエストが完了するまで、現在のスレッドがブロックされます.複数のHTTPリクエストを同時に発行すると、同期呼び出しのパフォーマンスが悪くなります.このとき,非同期呼び出しにより全体的な性能を向上させることができる.newCallメソッドで新しいCallオブジェクトを作成した後、executeメソッドで同期するのではなく、enqueueメソッドで実行キューに追加します.enqueueメソッドを呼び出すには、Callbackインタフェースの実装が必要です.Callbackインタフェース実装では,応答をonResponseとonFailure法により処理し,エラー処理を行う.非同期呼び出しの例

public class AsyncGet {
  public static void main(String[] args) throws IOException {
  OkHttpClient client = new OkHttpClient();

  Request request = new Request.Builder()
      .url("http://www.baidu.com")
      .build();

  client.newCall(request).enqueue(new Callback() {
    public void onFailure(Request request, IOException e) {
      e.printStackTrace();
    }

    public void onResponse(Response response) throws IOException {
      if (!response.isSuccessful()) {
        throw new IOException("      : " + response);
      }

      System.out.println(response.body().string());
    }
});
  }
}


okHttpで一番書きにくいところはCallbackだと思います.多くの人が出会うと信じています.Callbackが帰ってきたら、私のActivity finishか、私のFragment replaceになります.UIを変更すると、Viewが見つからないという問題が発生します.しかもCallbackが戻ってきたのは、backgroundThreadで、このときViewを操作するにはmainThreadに切り替えるのは、ちょっと面倒です.だから私が書いたときは、Callbackを使っていなかった以下にきれいなものを提供していました(自認...)の書き方を参考にさせていただきます.

/*  fragment   */

public class BaseFragment extends Fragment implements Handler.Callback {

private static final int MSG_QUERY_DATA = 0x00;
private static final int MSG_DISPLAY_DATA = 0x01;

@Override
public void onAttach(Activity activity) {
  super.onAttach(activity);
  this.activity = activity;

  /* setup handler */
  HandlerThread handlerThread = new HandlerThread(getClass().getName());
  handlerThread.start();
  backgroundHandler = new Handler(handlerThread.getLooper(), this);
  uiHandler = new Handler(activity.getMainLooper(), this);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {

  /* start */
  backgroundHandler.sendEmptyMessage(MSG_QUERY_DATA);
}

@Override
public void onDestroyView() {

  /* ��Message  ,backgroundThread�Y   */
  backgroundHandler.removeCallbacksAndMessages(null);
  uiHandler.removeCallbacksAndMessages(null);
  backgroundHandler.getLooper().quit();
  super.onDestroyView();
}

@Override
public boolean handleMessage(Message msg) {

  /*   fragment  Activity  ,  return ,  NPE */
  if (!isAdded()) return false;

  /*   �NMSG */
  switch(msg.what){

    case MSG_QUERY_DATA:

      // do okHttp without callback
      Response response = client.newCall(request).execute();

      // � � uiThread  UI  
      Message respMsg = uiHandler.obtainMessage();
      respMsg.what = MSG_DISPLAY_DATA;
      respMsg.obj = response;
      backgroundHandler.sendMessage(respMsg);
      break;

    case MSG_DISPLAY_DATA:

      Response apiResponse = (Response)msg.obj;

      //  ��
      if(null == apiResponse){
        //show error
      }

      //   
      else{
        //display data on UI
      }

      break;

    return false;
  }
}