无法使用 Retrofit 创建到 ESP8266 服务器的 HTTP POST
Cannot create HTTP POST to ESP8266 server using Retrofit
不知道这是否重要,但此操作是 RecycledView 对象的 onClickListener 方法的一部分。我正在尝试将 HTTP POST 发送到我的 esp8266 服务器。我的 phone 已连接到由 ESP8266 托管的 ACCESPOINT,其中还设置了服务器。
使用我的浏览器,我可以创建 POST 请求输入 URL :
http://192.168.11.4/register?WiFiSSID=wifissid&WiFiPassword=passssword&FirebaseUserToken=12122
一切正常。
当我尝试使用 Retrofit 执行相同操作时,我的应用程序崩溃并且日志显示:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.lightmeup, PID: 2805
java.lang.BootstrapMethodError: Exception from call site #4 bootstrap method
at okhttp3.internal.Util.<clinit>(Util.java:87)
at okhttp3.internal.Util.skipLeadingAsciiWhitespace(Util.java:321)
at okhttp3.HttpUrl$Builder.parse(HttpUrl.java:1313)
at okhttp3.HttpUrl.get(HttpUrl.java:917)
at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:492)
at com.example.lightmeup.Retrofit.RetrofitClient$instance.invoke(RetrofitClient.kt:12)
at com.example.lightmeup.Retrofit.RetrofitClient$instance.invoke(RetrofitClient.kt:6)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.example.lightmeup.Retrofit.RetrofitClient.getInstance(Unknown Source:7)
at com.example.lightmeup.NewDevice.NewDeviceViewHolder.onClick(NewDeviceViewHolder.kt:31)
at android.view.View.performClick(View.java:7352)
at android.view.View.performClickInternal(View.java:7318)
at android.view.View.access00(View.java:846)
at android.view.View$PerformClick.run(View.java:27800)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
Caused by: java.lang.ClassCastException: Bootstrap method returned null
at okhttp3.internal.Util.<clinit>(Util.java:87)
at okhttp3.internal.Util.skipLeadingAsciiWhitespace(Util.java:321)
at okhttp3.HttpUrl$Builder.parse(HttpUrl.java:1313)
at okhttp3.HttpUrl.get(HttpUrl.java:917)
at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:492)
at com.example.lightmeup.Retrofit.RetrofitClient$instance.invoke(RetrofitClient.kt:12)
at com.example.lightmeup.Retrofit.RetrofitClient$instance.invoke(RetrofitClient.kt:6)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.example.lightmeup.Retrofit.RetrofitClient.getInstance(Unknown Source:7)
at com.example.lightmeup.NewDevice.NewDeviceViewHolder.onClick(NewDeviceViewHolder.kt:31)
at android.view.View.performClick(View.java:7352)
at android.view.View.performClickInternal(View.java:7318)
at android.view.View.access00(View.java:846)
at android.view.View$PerformClick.run(View.java:27800)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
我的改装代码如下:
RetrofitClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object RetrofitClient {
private const val BASE_URL = "http://192.168.11.4/"
val instance: Api by lazy{
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
retrofit.create(Api::class.java)
}
}
Api
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.POST
interface Api {
@FormUrlEncoded
@POST("register")
fun sendRegisterInfo(
@Field("WiFiSSID") WiFiSSID:String,
@Field("WiFiPassword") WiFiPassword:String,
@Field("FirebaseUserToken") FirebaseUserToken:String
): Call<ResponseBody>
}
NewDeviceViewHolder
class NewDeviceViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
private lateinit var capabilities: String
init {
view.setOnClickListener {
WiFiConnector.setContext(view.context)
WiFiConnector.connect(view.context, view.textView_SSID.text.toString()) //Connecting to ESP8266 AccesPoint
var info = RegisterInfo("111222333", "Tajne_Haslo","TOKENnieDOpoznania")
RetrofitClient.instance.sendRegisterInfo(info.WiFiSSID, info.WiFiPassword, info.FirebaseUserToken)
.enqueue(object: Callback<ResponseBody>{
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
Toast.makeText(view.context, t.message, Toast.LENGTH_SHORT).show()
}
override fun onResponse(
call: Call<ResponseBody>,
response: Response<ResponseBody>
) {
Toast.makeText(view.context, response.body().toString(), Toast.LENGTH_SHORT).show()
}
})
}
}
@SuppressLint("SetTextI18n")
fun bind(newDevice: NewDevice) = with(view) {
textView_SSID.text = newDevice.SSID
textView_BSSID.text = newDevice.BSSID
textView_LEVEL.text = newDevice.LEVEL.toString() + "dB"
}
}
ESP8266服务器
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266WiFi.h>
String ssid = "LightMeUpe:" + WiFi.macAddress();
String password = "";
IPAddress ip(192,168,11,4);
IPAddress gateway(192,168,11,1);
IPAddress subnet(255,255,255,0);
ESP8266WebServer server(80);
void setup() {
Serial.begin(115200);
Serial.println("Configure Acces Point...");
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(ip,gateway,subnet);
WiFi.softAP(ssid,password);
Serial.print("IP address: ");
Serial.println(WiFi.softAPIP());
Serial.print("AP SSID: ");
Serial.println(ssid);
server.on("/",handleIndex);
server.on("/register",handleRegister);
server.begin();
Serial.println("HTTP server started");
Serial.println();
}
void loop() {
// put your main code here, to run repeatedly:
server.handleClient();
}
void handleIndex() {
server.send(200,"text/plain","OK");
}
void handleRegister() {
String WiFiSSID = server.arg("WiFiSSID");
String WiFiPassword = server.arg("WiFiPassword");
String FirebaseUserToken = server.arg("FirebaseUserToken");
Serial.println(WiFiSSID);
Serial.println(WiFiPassword);
Serial.println(FirebaseUserToken);
server.send(200,"text/plain","Registered");
}
不确定这是否会有所帮助,但您能否按照其他用户指出的情况尝试此操作,得到同样的异常。尝试在您的 app/build.gradle
中添加此内容可能与某些本机代码
存在兼容性问题
android {
//.... some other code
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
不知道这是否重要,但此操作是 RecycledView 对象的 onClickListener 方法的一部分。我正在尝试将 HTTP POST 发送到我的 esp8266 服务器。我的 phone 已连接到由 ESP8266 托管的 ACCESPOINT,其中还设置了服务器。
使用我的浏览器,我可以创建 POST 请求输入 URL :
http://192.168.11.4/register?WiFiSSID=wifissid&WiFiPassword=passssword&FirebaseUserToken=12122
一切正常。
当我尝试使用 Retrofit 执行相同操作时,我的应用程序崩溃并且日志显示:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.lightmeup, PID: 2805
java.lang.BootstrapMethodError: Exception from call site #4 bootstrap method
at okhttp3.internal.Util.<clinit>(Util.java:87)
at okhttp3.internal.Util.skipLeadingAsciiWhitespace(Util.java:321)
at okhttp3.HttpUrl$Builder.parse(HttpUrl.java:1313)
at okhttp3.HttpUrl.get(HttpUrl.java:917)
at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:492)
at com.example.lightmeup.Retrofit.RetrofitClient$instance.invoke(RetrofitClient.kt:12)
at com.example.lightmeup.Retrofit.RetrofitClient$instance.invoke(RetrofitClient.kt:6)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.example.lightmeup.Retrofit.RetrofitClient.getInstance(Unknown Source:7)
at com.example.lightmeup.NewDevice.NewDeviceViewHolder.onClick(NewDeviceViewHolder.kt:31)
at android.view.View.performClick(View.java:7352)
at android.view.View.performClickInternal(View.java:7318)
at android.view.View.access00(View.java:846)
at android.view.View$PerformClick.run(View.java:27800)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
Caused by: java.lang.ClassCastException: Bootstrap method returned null
at okhttp3.internal.Util.<clinit>(Util.java:87)
at okhttp3.internal.Util.skipLeadingAsciiWhitespace(Util.java:321)
at okhttp3.HttpUrl$Builder.parse(HttpUrl.java:1313)
at okhttp3.HttpUrl.get(HttpUrl.java:917)
at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:492)
at com.example.lightmeup.Retrofit.RetrofitClient$instance.invoke(RetrofitClient.kt:12)
at com.example.lightmeup.Retrofit.RetrofitClient$instance.invoke(RetrofitClient.kt:6)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.example.lightmeup.Retrofit.RetrofitClient.getInstance(Unknown Source:7)
at com.example.lightmeup.NewDevice.NewDeviceViewHolder.onClick(NewDeviceViewHolder.kt:31)
at android.view.View.performClick(View.java:7352)
at android.view.View.performClickInternal(View.java:7318)
at android.view.View.access00(View.java:846)
at android.view.View$PerformClick.run(View.java:27800)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
我的改装代码如下:
RetrofitClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object RetrofitClient {
private const val BASE_URL = "http://192.168.11.4/"
val instance: Api by lazy{
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
retrofit.create(Api::class.java)
}
}
Api
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.POST
interface Api {
@FormUrlEncoded
@POST("register")
fun sendRegisterInfo(
@Field("WiFiSSID") WiFiSSID:String,
@Field("WiFiPassword") WiFiPassword:String,
@Field("FirebaseUserToken") FirebaseUserToken:String
): Call<ResponseBody>
}
NewDeviceViewHolder
class NewDeviceViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
private lateinit var capabilities: String
init {
view.setOnClickListener {
WiFiConnector.setContext(view.context)
WiFiConnector.connect(view.context, view.textView_SSID.text.toString()) //Connecting to ESP8266 AccesPoint
var info = RegisterInfo("111222333", "Tajne_Haslo","TOKENnieDOpoznania")
RetrofitClient.instance.sendRegisterInfo(info.WiFiSSID, info.WiFiPassword, info.FirebaseUserToken)
.enqueue(object: Callback<ResponseBody>{
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
Toast.makeText(view.context, t.message, Toast.LENGTH_SHORT).show()
}
override fun onResponse(
call: Call<ResponseBody>,
response: Response<ResponseBody>
) {
Toast.makeText(view.context, response.body().toString(), Toast.LENGTH_SHORT).show()
}
})
}
}
@SuppressLint("SetTextI18n")
fun bind(newDevice: NewDevice) = with(view) {
textView_SSID.text = newDevice.SSID
textView_BSSID.text = newDevice.BSSID
textView_LEVEL.text = newDevice.LEVEL.toString() + "dB"
}
}
ESP8266服务器
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266WiFi.h>
String ssid = "LightMeUpe:" + WiFi.macAddress();
String password = "";
IPAddress ip(192,168,11,4);
IPAddress gateway(192,168,11,1);
IPAddress subnet(255,255,255,0);
ESP8266WebServer server(80);
void setup() {
Serial.begin(115200);
Serial.println("Configure Acces Point...");
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(ip,gateway,subnet);
WiFi.softAP(ssid,password);
Serial.print("IP address: ");
Serial.println(WiFi.softAPIP());
Serial.print("AP SSID: ");
Serial.println(ssid);
server.on("/",handleIndex);
server.on("/register",handleRegister);
server.begin();
Serial.println("HTTP server started");
Serial.println();
}
void loop() {
// put your main code here, to run repeatedly:
server.handleClient();
}
void handleIndex() {
server.send(200,"text/plain","OK");
}
void handleRegister() {
String WiFiSSID = server.arg("WiFiSSID");
String WiFiPassword = server.arg("WiFiPassword");
String FirebaseUserToken = server.arg("FirebaseUserToken");
Serial.println(WiFiSSID);
Serial.println(WiFiPassword);
Serial.println(FirebaseUserToken);
server.send(200,"text/plain","Registered");
}
不确定这是否会有所帮助,但您能否按照其他用户指出的情况尝试此操作,得到同样的异常。尝试在您的 app/build.gradle
中添加此内容可能与某些本机代码
android {
//.... some other code
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}