1.若想在 Callback 中修改畫面(包含產生 Dialog, Toast 等等),必須使用 runonUiThread 包含要更改的畫面的行為,如下為使用 OKHttp 包裝器的方法宣告,

  public static void sendPostWithJSONFormat(String URL, Map<String, String> requestParameter, Callback callback) {
    MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    RequestBody requestBody = RequestBody.create(JSON, new JSONObject(requestParameter).toString());
    Request request = new Request.Builder().url(URL).post(requestBody).build();
    Call call = sOKHttpClient.newCall(request);
    call.enqueue(callback);
  }

以下是使用該包裝器方法的範例

    OKHttpWrapper.sendPostWithJSONFormat(URL, httpParameter, new Callback() {
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                 //更改畫面行為
                }
                @Override
                public void onFailure(Call call, IOException e) {
                 //更改畫面行為
                }
            });

重點在於第 4 行和第 9 行若有更改畫面的行為必須使用 runOnUiThread 去包含。否則會出現以下 Exception:

E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
    java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
        at android.os.Handler.<init>(Handler.java:200)
        at android.os.Handler.<init>(Handler.java:114)
        at android.app.Dialog.<init>(Dialog.java:119)
        at android.app.AlertDialog.<init>(AlertDialog.java:200)
        at android.app.AlertDialog$Builder.create(AlertDialog.java:1086)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)