Android侦听器模式与回调模式

时间:2015-12-16 06:49:47

标签: android design-patterns okhttp

当我在OkHttp中处理网络功能时,我遇到的主要有两种模式:

  1. 听众模式
  2. 回调模式
  3. 听众模式示例:

    // Listener class
    public interface NetworkListener {
        void onFailure(Request request, IOException e);
        void onResponse(Response response);
    }
    
    // NetworkManager class
    public class NetworkManager {
        static String TAG = "NetworkManager";
        public NetworkListener listener;
        OkHttpClient client = new OkHttpClient();
        public void setListener(NetworkListener listener) {
            this.listener = listener;
        }
        void post(String url, JSONObject json) throws IOException {
            //RequestBody body = RequestBody.create(JSON, json);
            try {
                JSONArray array = json.getJSONArray("d");
                RequestBody body = new FormEncodingBuilder()
                        .add("m", json.getString("m"))
                        .add("d", array.toString())
                        .build();
                Request request = new Request.Builder()
                        .url(url)
                        .post(body)
                        .build();
    
                // Asynchronous Mode
                client.newCall(request).enqueue(new Callback() {
                    @Override
                    public void onFailure(Request request, IOException e) {
                        Log.e(TAG, e.toString());
                        if(listener != null) {
                            listener.onFailure(request, e);
                        }
                    }
    
                    @Override
                    public void onResponse(Response response) throws IOException {
                        Log.w(TAG, response.body().string());
                        if(listener != null) {
                            listener.onResponse(response);
                        }
    
                    }
                });
            } catch (JSONException jsone) {
                Log.e(TAG, jsone.getMessage());
            }
        }
    }
    
    // In the Activity
    NetworkManager manager = new NetworkManager();
    manager.setListener(this);
    try {
      requestState = RequestState.REQUESTING;
      manager.post("http://www.example.com/api.php", reqObj);
    } catch(IOException ioe) {
      Log.e(TAG, ioe.getMessage());
    }
    

    回调模式示例:

    // in onCreate
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
            doGET(new Callback() {
                @Override
                public void onFailure(Request request, IOException e) {
                    Log.d("OkHttp", "Shit happens");
                }
    
                @Override
                public void onResponse(Response response) throws IOException {
                    if (response.isSuccessful()) {
                        String strResponse = response.body().string();
                        Gson gson = new Gson();
                        Wrapper wrapper = gson.fromJson(strResponse, Wrapper.class);
                        Log.d("OkHttp", wrapper.getListContents());
                    } else {
                        Log.d("OkHttp", "Request not successful");
                    }
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    
    Call doGET(Callback callback) throws IOException {
        // Start Network Request
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url("http://www.example.com/api.php").build();
        Call call  = client.newCall(request);
        call.enqueue(callback);
        return call;
    }
    

    使用上述2种模式有哪些优点和缺点?

1 个答案:

答案 0 :(得分:2)

恕我直言,他们没有什么不同,实际上你可以发现Callback也是一个界面。

package com.squareup.okhttp;

import java.io.IOException;

public interface Callback {
  /**
   * Called when the request could not be executed due to cancellation, a
   * connectivity problem or timeout. Because networks can fail during an
   * exchange, it is possible that the remote server accepted the request
   * before the failure.
   */
  void onFailure(Request request, IOException e);

  /**
   * Called when the HTTP response was successfully returned by the remote
   * server. The callback may proceed to read the response body with {@link
   * Response#body}. The response is still live until its response body is
   * closed with {@code response.body().close()}. The recipient of the callback
   * may even consume the response body on another thread.
   *
   * <p>Note that transport-layer success (receiving a HTTP response code,
   * headers and body) does not necessarily indicate application-layer
   * success: {@code response} may still indicate an unhappy HTTP response
   * code like 404 or 500.
   */
  void onResponse(Response response) throws IOException;
}

但是,当我想重用一些代码(或构建一个util类)时,我经常使用如下:

接口:

public interface OkHttpListener {
    void onFailure(Request request, IOException e);
    void onResponse(Response response) throws IOException;
}

Util类:

public class OkHttpUtils {
    public static void getData(String url, final OkHttpListener listener){
        OkHttpClient client = new OkHttpClient();
        // GET request
        Request request = new Request.Builder()
                .url(url)
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                listener.onFailure(request, e);
            }
            @Override
            public void onResponse(Response response) throws IOException {
                listener.onResponse(response);
            }
        });
    }


// the following uses built-in okhttp's Callback interface
    public static void getData2(String url, Callback callbackListener){
        OkHttpClient client = new OkHttpClient();
        // GET request
        Request request = new Request.Builder()
                .url(url)
                .build();
        client.newCall(request).enqueue(callbackListener);
    }
    // other methods...
}

然后在活动类中:

       OkHttpListener listener = new OkHttpListener() {
            @Override
            public void onFailure(Request request, IOException e) {
                Log.e(LOG_TAG, e.toString());
            }

            @Override
            public void onResponse(Response response) throws IOException {
                String responseBody = response.body().string();
                Log.i(LOG_TAG, responseBody);
            }
        };
        String url = "http://myserver/api/getvalues";
        OkHttpUtils.getData(url, listener);
        String url1 = "http://myserver/api/getvalues/123";
        OkHttpUtils.getData(url1, listener);

       Callback callbackListener = new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                Log.e(LOG_TAG, e.toString());
            }

            @Override
            public void onResponse(Response response) throws IOException {
                String responseBody = response.body().string();
                Log.i(LOG_TAG, responseBody);
            }
        };

        String url = "http://myserver/api/getvalues";
        OkHttpUtils.getData2(url, callbackListener);
        String url1 = "http://myserver/api/getvalues/123";
        OkHttpUtils.getData2(url1, callbackListener);

希望它有所帮助!