okhttp3:从 Android 写入 MySQL

okhttp3 : writing to MySQL from Android

我现在花了很长时间试图找出如何从我的 Android 应用程序写入 Web 服务器上的 MySQL。我计划使用来自 Android 的数据在 table 中执行更新。我有一个似乎可以工作的 PHP 页面,至少当我从 Firefox 中的 HTTRequester 模块调用它时是这样。

HttpRequest 设置了一个名为 "request" 的参数及其值:

{"Temp":"34.4","McsObservation":4,"McsSensation":4,"Id_day":9,"DateCycle":"2015-12-01","Id_profile":"672"}

当我向 php 提交 POST 时,table 会更新。

然而,在Android中,当我执行下面的代码时,我得到了消息"Unfortunately MyApplication has stopped"

temp_quick.java包括:

btnUpdateTemp.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
         //MyPostTemp.Post
        PostTemperature quick_temp = new PostTemperature();
        String json = quick_temp.QuickTempJson(42, "36.66");
        outputResult.setText(json);
        String response = null;
        try {
            response = quick_temp.post("http://MyWeb.fr/Inverseo/insert_mesure.php", json);
        } catch (IOException e) {
            e.printStackTrace();
        }
       System.out.println(response);

然后在PostTemperature.java:

package com.inverseo.marc.t372lematin;

//test HttpURLConnection
import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class PostTemperature {
// ex with OKHttp

public static final MediaType JSON
        = MediaType.parse("application/json; charset=utf-8");

OkHttpClient client = new OkHttpClient();

        String post(String url, String json) throws IOException {
            RequestBody body = RequestBody.create(JSON, json);
            Request request = new Request.Builder()
                    .url(url)
                    .post(body)
                    .build();
            Response response = client.newCall(request).execute();
            return response.body().string();
        }

        String QuickTempJson(Integer id_day, String temp) {
            return "{\"request\":{" +
                        "\"Temp\":\"" + temp + "\","
                        + "\"McsObservation\":1,"
                        + "\"McsSensation\":2,"
                        + "\"Id_day\":" + id_day + ","
                        + "\"DateCycle\":\"2015-11-03\","
                        + "\"Id_profile\":\"1394\"}"
                        + "}" ;
    }

我得到的logcat是这样的:

01-25 22:00:25.364 1924-1924/? E/AndroidRuntime: FATAL EXCEPTION: main
     Process: com.inverseo.marc.myapplic, PID: 1924
     android.os.NetworkOnMainThreadException
         at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
         at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
         at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
         at java.net.InetAddress.getAllByName(InetAddress.java:214)
         at okhttp3.Dns.lookup(Dns.java:39)
         at okhttp3.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:173)
         at okhttp3.internal.http.RouteSelector.nextProxy(RouteSelector.java:139)
         at okhttp3.internal.http.RouteSelector.next(RouteSelector.java:81)
         at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174)
         at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:127)
         at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
         at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:289)
         at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:241)
         at okhttp3.RealCall.getResponse(RealCall.java:240)
         at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
         at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
         at okhttp3.RealCall.execute(RealCall.java:57)
         at com.inverseo.marc.t372lematin.PostTemperature.post(PostTemperature.java:37)
         at com.inverseo.marc.t372lematin.temp_quick.onClick(temp_quick.java:322)
         at android.view.View.performClick(View.java:4438)
         at android.view.View$PerformClick.run(View.java:18422)
         at android.os.Handler.handleCallback(Handler.java:733)
         at android.os.Handler.dispatchMessage(Handler.java:95)
         at android.os.Looper.loop(Looper.java:136)
         at android.app.ActivityThread.main(ActivityThread.java:5017)
         at java.lang.reflect.Method.invokeNative(Native Method)
         at java.lang.reflect.Method.invoke(Method.java:515)
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
         at dalvik.system.NativeStart.main(Native Method)

在此先感谢您提供制作此 运行 的任何线索。

关键在于异常:android.os.NetworkOnMainThreadException。在 Android 世界中,您不能在主线程上进行网络调用。由于您是从 OnClickListener 调用 post(),因此您是在主线程上进行网络调用。您需要将对 post() 的调用移至后台线程。您可以通过使用 ThreadAsyncTask(基本上是在 Android 上执行后台线程的一种很好、简单的方法)或 OkHttp 的 Callback 来完成此操作。这里有一个例子:https://github.com/square/okhttp/wiki/Recipes.

我从来没有直接使用过 OkHttp,但是这里有一个如何使用他们的异步的例子 api:

String json = "<YOUR JSON STRING>";
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
        .url("http://MyWeb.fr/Inverseo/insert_mesure.php")
        .post(RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), json))
        .build();

client.newCall(request).enqueue(new Callback() {
  @Override
  public void onFailure(Call call, IOException e) {
    // Request failed
  }

  @Override
  public void onResponse(Call call, Response response) throws IOException {
    // Handle whatever comes back from the server
  }
});