我想在Android中使用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 response = post("http://www.roundsapp.com/post", json);
此调用以 NetworkOnMainThreadException 结尾 我可以使用AsyncTask包装调用,但据我从示例中了解,OkHttp库应该已经处理过了.. 我做错了吗?
答案 0 :(得分:46)
你应该使用OkHttp的异步方法。
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
Call post(String url, String json, Callback callback) {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Call call = client.newCall(request);
call.enqueue(callback);
return call;
}
然后你的回复将在回调中处理(OkHttp 2.x):
post("http://www.roundsapp.com/post", json, new Callback() {
@Override
public void onFailure(Request request, Throwable throwable) {
// Something went wrong
}
@Override public void onResponse(Response response) throws IOException {
if (response.isSuccessful()) {
String responseStr = response.body().string();
// Do what you want to do with the response.
} else {
// Request not successful
}
}
});
或OkHttp 3.x:
post("http://www.roundsapp.com/post", "", new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// Something went wrong
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String responseStr = response.body().string();
// Do what you want to do with the response.
} else {
// Request not successful
}
}
});
查看他们的食谱以获取更多示例:https://github.com/square/okhttp/wiki/Recipes
答案 1 :(得分:4)
根据OkHttp文档: 它支持同步阻塞调用和带回调的异步调用。 您的示例是在主线程和Android上,因为如果您尝试在主线程
上进行网络调用,则3.0版会抛出该异常更好的选择是将它与改造和Gson一起使用: http://square.github.io/retrofit/ https://code.google.com/p/google-gson/
以下是示例: http://engineering.meetme.com/2014/03/best-practices-for-consuming-apis-on-android/ http://heriman.net/?p=5
答案 2 :(得分:0)
如果您按照这些步骤实施OKHTTP,那么您绝对只需要应用两行代码即可在多个屏幕上调用多个API
UpdateListener updateListener = new UpdateListener(HitAPIActivity.this, baseHTTPRequest);
updateListener.getJsonData();
第1步:
baseHTTPRequest = new BaseHTTPRequest();
// baseHTTPRequest.setURL("https://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demohttps://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo");
baseHTTPRequest.setURL("http://jsonparsing.parseapp.com/jsonData/moviesDemoItem.txt");
baseHTTPRequest.setRequestCode(reqType);
baseHTTPRequest.setCachedRequired(true);
UpdateListener updateListener = new UpdateListener(HitAPIActivity.this, baseHTTPRequest);
updateListener.executeRequest();
第2步:创建请求类
/ ** *由Deepak Sharma于4/7/16创建。 *这是一个具有基本参数的HTTP请求类。 *如果您想添加更多参数,请创建该类的子类 *并添加您的子类。不要修改这个课程。 * /
public class BaseHTTPRequest<T> {
private Context context;
private String URL;
private int requestCode;
private List<T> listParameters;
private String header;
private boolean isCachedRequired;
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
public void setURL(String URL) {
this.URL = URL;
}
public String getURL() {
return URL;
}
public int getRequestCode() {
return requestCode;
}
public void setRequestCode(int requestCode) {
this.requestCode = requestCode;
}
public List<T> getListParameters() {
return listParameters;
}
public void setListParameters(List<T> listParameters) {
this.listParameters = listParameters;
}
public String getHeader() {
return header;
}
public void setHeader(String header) {
this.header = header;
}
public boolean isCachedRequired() {
return isCachedRequired;
}
public void setCachedRequired(boolean cachedRequired) {
isCachedRequired = cachedRequired;
}
}
第4步:创建一个监听器类
import android.util.Log; import com.google.gson.Gson; import java.io.IOException; import dxswifi_direct.com.wifidirectcommunication.base.model.request.BaseHTTPRequest; import okhttp3.Call; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Callback; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response;
/ ** *由Deepak Sharma于4/7/16创建。 * @email:dpsharma.sharma1@gmail.com *这是一个简单的java类,它将帮助您进行HTTP请求/响应,它会 *抛出对应活动的回复。 * /
public class UpdateListener {
private OnUpdateViewListener onUpdateViewListener;
OkHttpClient okHttpClient = new OkHttpClient();
BaseHTTPRequest mRequestModel;
private String mURL = null;
private Request mRequest = null;
public interface OnUpdateViewListener {
void updateView(String responseString, boolean isSuccess,int reqType);
}
public UpdateListener(OnUpdateViewListener onUpdateView, final BaseHTTPRequest requestModel) {
this.mRequestModel = requestModel;
this.onUpdateViewListener = onUpdateView;
if (requestModel.isCachedRequired())
{
/*File httpCacheDirectory = new File(requestModel.getContext().getCacheDir(), "responses");
Cache cache = null;
cache = new Cache(httpCacheDirectory, 10 * 1024 * 1024);
if (cache != null) {
okHttpClient.setCache(cache);
}*/
}
/*mURL = null;
if (requestModel.getListParameters()!=null && requestModel.getListParameters().size()>0)
{
HttpUrl.Builder urlBuilder = HttpUrl.parse(requestModel.getURL()).newBuilder();
List<RequestParameter> requestParameters = requestModel.getListParameters();
for (int i=0; i<requestParameters.size();i++)
{
urlBuilder.addQueryParameter(requestParameters.get(i).getKey(),requestParameters.get(i).getValue());
}
mURL = urlBuilder.build().toString();
}
else
{
mURL = requestModel.getURL();
}*/
mURL = requestModel.getURL();
if (mRequestModel.getListParameters()!=null && mRequestModel.getListParameters().size()>1)
{
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
mRequest = new Request.Builder()
.url(mURL)
.post(RequestBody.create(JSON, new Gson().toJson(BaseHTTPRequest.class)))
.build();
}
else
{
mRequest = new Request.Builder()
.url(mURL)
.build();
}
}
public void executeRequest()
{
Call call = okHttpClient.newCall(mRequest);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
onUpdateViewListener.updateView(NetworkException.getErrorMessage(e), false, mRequestModel.getRequestCode());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
// You can also throw your own custom exception
throw new IOException("Unexpected code " + response);
} else {
Log.i("Response:",response.toString());
Log.i("Response body:",response.body().toString());
Log.i("Response message:",response.message());
onUpdateViewListener.updateView(response.body().string(),true, mRequestModel.getRequestCode());
}
// do something wih the result
}
});
}
}
步骤5:从您请求的活动中,实现监听器
public class HitAPIActivity extends AppCompatActivity implements View.OnClickListener, UpdateListener.OnUpdateViewListener{
@Override
public void updateView(final String responseString, boolean isSuccess, int reqType) {
if (isSuccess)
{
if (!responseString.contains("failure")
&& !responseString.contains("Error")) {
// Handle request on the basis of Request Type.
switch (reqType) {
case ApiConstants.GET_CONTACTS:
break;
default:
break;
}
}
}
}