在后台线程中执行OkHttp网络操作

5
我正在使用OKHttp向服务器发送Post请求,如下所示:
public class NetworkManager {
    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    OkHttpClient client = new OkHttpClient();

    String post(String url, JSONObject json) throws IOException {
        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();
            Response response = client.newCall(request).execute();
            return response.body().string();
        } catch (JSONException jsone) {
            return "ERROR: " + jsone.getMessage();
        }
    }
}

并通过以下方式调用:

NetworkManager manager = new NetworkManager();
String response = manager.post("http://www.example.com/api/", jsonObject);

当我尝试运行App时,在logcat中会提示错误:
android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
参考其他SO的问题,我添加了以下内容来覆盖该策略:
if (android.os.Build.VERSION.SDK_INT > 9)
{
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
}

然而,我认为这是不健康的,我想将NetworkManager的操作放到后台。怎样做呢?

1个回答

12

由于OkHttp也支持异步方式,所以我认为您可以参考以下GET请求示例,然后应用于您的POST请求:

        OkHttpClient client = new OkHttpClient();
        // GET request
        Request request = new Request.Builder()
                .url("http://google.com")
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                Log.e(LOG_TAG, e.toString());
            }
            @Override
            public void onResponse(Response response) throws IOException {
                Log.w(LOG_TAG, response.body().string());
                Log.i(LOG_TAG, response.toString());
            }
        });

希望有所帮助!


1
建议使用OkHttp异步选项。 - novak
看起来很有前途。当响应准备好时,我该如何通知主类?我的当前逻辑是同步的,并直接返回响应字符串,然后主类解析响应以执行进一步的操作。 - Raptor
2
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - BNK
2
你可以参考我的GitHub示例项目,这是一个POST请求。https://github.com/ngocchung/MultipartOkHttp - BNK
很好的例子,但只有一个问题还未解决。我需要在调用“NetworkManager”的类(“MainActivity”)中更新一个变量。我该如何在“MainActivity”上调用一个函数? - Raptor
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接