当我尝试 return http 响应时应用程序崩溃
App crashing when I try and return http response
我做了一个 java class 来处理 HTTP post 请求,它以字符串形式发回结果。出于某种原因,当我发送请求时,我可以将响应打印到日志中,但是当 return 响应字符串更新 UI 时,我的应用程序崩溃了。任何人都可以解释这里发生了什么吗?我正努力在 java 方面做得更好,因此请指出任何其他不良做法,我们将不胜感激。
日志:
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
D/OKHTTP3: Request body created
D/OKHTTP3: Request body created 2
D/OKHTTP3: Got Response
D/OKHTTP3: {
"failed": "Asset already exists"
}
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.john.okhttp, PID: 3166
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:318)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.IllegalStateException: closed
at okhttp3.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:374)
at okio.Buffer.writeAll(Buffer.java:993)
at okio.RealBufferedSource.readByteArray(RealBufferedSource.java:106)
at okhttp3.ResponseBody.bytes(ResponseBody.java:128)
at okhttp3.ResponseBody.string(ResponseBody.java:154)
at com.example.john.okhttp.PostEx.doPostRequest(PostEx.java:40)
at com.example.john.okhttp.MainActivity$Requesting.doInBackground(MainActivity.java:59)
at com.example.john.okhttp.MainActivity$Requesting.doInBackground(MainActivity.java:51)
at android.os.AsyncTask.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Application terminated.
来自两个 java 文件的代码将被 post 编辑如下:
MainActivity.java:
package com.example.john.okhttp;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.json.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class MainActivity extends AppCompatActivity {
private Button btnSendHttpRequest;
private EditText etJsonResponse;
private TextView View;
private TextView View2;
private OkHttpClient okHttpClient;
private Request request;
public final String URL = "http://www.mocky.io/v2/582ac99c280000d50953c316";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set button and text view values
btnSendHttpRequest = (Button) findViewById(R.id.btnSendRequest);
View = (TextView) findViewById(R.id.view1);
View2 = (TextView) findViewById(R.id.textView4);
etJsonResponse = (EditText) findViewById(R.id.etjson);
//response for button
btnSendHttpRequest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//http request
PostEx example = new PostEx();
new Requesting().execute();
}
});
}
public class Requesting extends AsyncTask<String, String, String> {
// post request stuff
@Override
protected String doInBackground(String... params) {
String id = "444454";
String userName = "john";
PostEx example = new PostEx();
String jsonstr = example.makeJsonForUser(id, userName);
if(example.doPostRequest(jsonstr)== null){
Log.d("OKHTTP3", "null pointer");
}
String response = example.doPostRequest(jsonstr);
Log.d("OKHTTP3", "sending response");
return response;
}
@Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
//rewrite text view
try {
// create json ob from response
if(response == null){
Log.d("OKHTTP3", "null pointer");
}
JSONObject jsonObj = new JSONObject(response);
//get the values from the json key value pairs
String id = jsonObj.toString();
//update the text views
TextView textView = (TextView) findViewById(R.id.view1);
textView.setText(id);
} catch (Exception e) {
}
}
}
}
PostEx.java:
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class PostEx {
public String doPostRequest(String jsonstr) {
String url = "http://45.55.92.243/newuser";
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON,jsonstr);
Log.d("OKHTTP3","Request body created");
Request newReq = new Request.Builder()
.url(url)
.post(body)
.build();
Log.d("OKHTTP3","Request body created 2");
try {
Response response = client.newCall(newReq).execute();
Log.d("OKHTTP3","Got Response");
Log.d("OKHTTP3",response.body().string());
String Fresponse = response.body().string();
response.close();
return Fresponse;
} catch (IOException e) {
Log.d("OKHTTP3","Got Exception");
e.printStackTrace();
return null;
}
}
public String makeJsonForUser(String id, String Username){
JSONObject data = new JSONObject();
try {
data.put("id", id);
data.put("name", Username);
return data.toString();
} catch (JSONException e) {
Log.d("OKHTTP3", "JSON Exeption");
e.printStackTrace();
return null;
}
}
}
在 okhttp3.ResponseBody.string(ResponseBody.java:154):
public final String string() throws IOException {
return new String(bytes(), charset().name());
}
在 okhttp3.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:374):
@Override public long read(Buffer sink, long byteCount) throws IOException {
if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
if (closed) throw new IllegalStateException("closed");
if (bytesRemaining == 0) return -1;
long read = source.read(sink, Math.min(bytesRemaining, byteCount));
if (read == -1) {
endOfInput(false); // The server didn't supply the promised content length.
throw new ProtocolException("unexpected end of stream");
}
bytesRemaining -= read;
if (bytesRemaining == 0) {
endOfInput(true);
}
return read;
}
到目前为止,您的代码大部分都有效
D/OKHTTP3: Request body created
D/OKHTTP3: Request body created 2
D/OKHTTP3: Got Response
我记得读书,you can only receive the body string once
// Log.d("OKHTTP3",response.body().string());
String Fresponse = response.body().string();
// log Fresponse here
并在捕获
之后关闭 finally
块中的资源
更重要的是你在使用 Okhttp。你不需要异步任务!在客户端调用对象
上使用 enqueue
方法而不是 execute
client.newCall(newReq).enqueue(new Callback() {
// handle response here
});
并且您正在处理 JSON,因此 Retrofit 将帮助您实现您已经尝试做的事情
问题是您可以调用 string()
一次。但是不知道为什么
我做了一个 java class 来处理 HTTP post 请求,它以字符串形式发回结果。出于某种原因,当我发送请求时,我可以将响应打印到日志中,但是当 return 响应字符串更新 UI 时,我的应用程序崩溃了。任何人都可以解释这里发生了什么吗?我正努力在 java 方面做得更好,因此请指出任何其他不良做法,我们将不胜感激。
日志:
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
D/OKHTTP3: Request body created
D/OKHTTP3: Request body created 2
D/OKHTTP3: Got Response
D/OKHTTP3: {
"failed": "Asset already exists"
}
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.john.okhttp, PID: 3166
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:318)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.IllegalStateException: closed
at okhttp3.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:374)
at okio.Buffer.writeAll(Buffer.java:993)
at okio.RealBufferedSource.readByteArray(RealBufferedSource.java:106)
at okhttp3.ResponseBody.bytes(ResponseBody.java:128)
at okhttp3.ResponseBody.string(ResponseBody.java:154)
at com.example.john.okhttp.PostEx.doPostRequest(PostEx.java:40)
at com.example.john.okhttp.MainActivity$Requesting.doInBackground(MainActivity.java:59)
at com.example.john.okhttp.MainActivity$Requesting.doInBackground(MainActivity.java:51)
at android.os.AsyncTask.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Application terminated.
来自两个 java 文件的代码将被 post 编辑如下:
MainActivity.java:
package com.example.john.okhttp;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.json.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class MainActivity extends AppCompatActivity {
private Button btnSendHttpRequest;
private EditText etJsonResponse;
private TextView View;
private TextView View2;
private OkHttpClient okHttpClient;
private Request request;
public final String URL = "http://www.mocky.io/v2/582ac99c280000d50953c316";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set button and text view values
btnSendHttpRequest = (Button) findViewById(R.id.btnSendRequest);
View = (TextView) findViewById(R.id.view1);
View2 = (TextView) findViewById(R.id.textView4);
etJsonResponse = (EditText) findViewById(R.id.etjson);
//response for button
btnSendHttpRequest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//http request
PostEx example = new PostEx();
new Requesting().execute();
}
});
}
public class Requesting extends AsyncTask<String, String, String> {
// post request stuff
@Override
protected String doInBackground(String... params) {
String id = "444454";
String userName = "john";
PostEx example = new PostEx();
String jsonstr = example.makeJsonForUser(id, userName);
if(example.doPostRequest(jsonstr)== null){
Log.d("OKHTTP3", "null pointer");
}
String response = example.doPostRequest(jsonstr);
Log.d("OKHTTP3", "sending response");
return response;
}
@Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
//rewrite text view
try {
// create json ob from response
if(response == null){
Log.d("OKHTTP3", "null pointer");
}
JSONObject jsonObj = new JSONObject(response);
//get the values from the json key value pairs
String id = jsonObj.toString();
//update the text views
TextView textView = (TextView) findViewById(R.id.view1);
textView.setText(id);
} catch (Exception e) {
}
}
}
}
PostEx.java:
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class PostEx {
public String doPostRequest(String jsonstr) {
String url = "http://45.55.92.243/newuser";
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON,jsonstr);
Log.d("OKHTTP3","Request body created");
Request newReq = new Request.Builder()
.url(url)
.post(body)
.build();
Log.d("OKHTTP3","Request body created 2");
try {
Response response = client.newCall(newReq).execute();
Log.d("OKHTTP3","Got Response");
Log.d("OKHTTP3",response.body().string());
String Fresponse = response.body().string();
response.close();
return Fresponse;
} catch (IOException e) {
Log.d("OKHTTP3","Got Exception");
e.printStackTrace();
return null;
}
}
public String makeJsonForUser(String id, String Username){
JSONObject data = new JSONObject();
try {
data.put("id", id);
data.put("name", Username);
return data.toString();
} catch (JSONException e) {
Log.d("OKHTTP3", "JSON Exeption");
e.printStackTrace();
return null;
}
}
}
在 okhttp3.ResponseBody.string(ResponseBody.java:154):
public final String string() throws IOException {
return new String(bytes(), charset().name());
}
在 okhttp3.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:374):
@Override public long read(Buffer sink, long byteCount) throws IOException {
if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
if (closed) throw new IllegalStateException("closed");
if (bytesRemaining == 0) return -1;
long read = source.read(sink, Math.min(bytesRemaining, byteCount));
if (read == -1) {
endOfInput(false); // The server didn't supply the promised content length.
throw new ProtocolException("unexpected end of stream");
}
bytesRemaining -= read;
if (bytesRemaining == 0) {
endOfInput(true);
}
return read;
}
到目前为止,您的代码大部分都有效
D/OKHTTP3: Request body created
D/OKHTTP3: Request body created 2
D/OKHTTP3: Got Response
我记得读书,you can only receive the body string once
// Log.d("OKHTTP3",response.body().string());
String Fresponse = response.body().string();
// log Fresponse here
并在捕获
之后关闭finally
块中的资源
更重要的是你在使用 Okhttp。你不需要异步任务!在客户端调用对象
上使用enqueue
方法而不是 execute
client.newCall(newReq).enqueue(new Callback() {
// handle response here
});
并且您正在处理 JSON,因此 Retrofit 将帮助您实现您已经尝试做的事情
问题是您可以调用 string()
一次。但是不知道为什么