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()
的调用移至后台线程。您可以通过使用 Thread
、AsyncTask
(基本上是在 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
}
});
我现在花了很长时间试图找出如何从我的 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()
的调用移至后台线程。您可以通过使用 Thread
、AsyncTask
(基本上是在 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
}
});