所以,也许有一点Square Square的OkHttp库Android的经验稍多一点的人可以向我解释到底发生了什么。我理解UI线程的概念和对Web的异步请求,以免混乱UI线程。我的问题是,为什么我的代码在收到响应之前进行响应?我该如何解决这个问题?尽管这里是我的代码,但出于安全原因,我将忽略我所调用的实际URL,但它应该返回的响应也会在下面发布。现在异步检索JSON数据
package com.example.jeffrey.yetiagenda.ui;
import android.app.Activity;
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 android.widget.Toast;
import com.example.jeffrey.yetiagenda.R;
import com.example.jeffrey.yetiagenda.api.API;
import com.example.jeffrey.yetiagenda.api.User;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.json.JSONException;
import java.io.IOException;
import butterknife.ButterKnife;
import butterknife.InjectView;
public class YetiAgenda extends Activity {
public static final String TAG = YetiAgenda.class.getSimpleName();
public String mJSONData;
@InjectView(R.id.usernameEdit)
EditText mUsernameEdit;
@InjectView(R.id.passwordEdit)
EditText mPasswordEdit;
@InjectView(R.id.loginButton)
Button mLoginButton;
@InjectView(R.id.invalidLoginText)
TextView mInvalidLoginText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_yeti_agenda);
ButterKnife.inject(this);
mInvalidLoginText.setVisibility(View.INVISIBLE);
//if login is successful, pass id of user to next activity to construct
mLoginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
mJSONData = null; // for debugging, read below
if (APICall("(removed for security reasons)")) {
hoorayToast();
} else {
booToast();
}
} catch (JSONException e) {
Log.e(TAG, "Exception caught:", e);
}
}
});
}
public void hoorayToast() {
Toast.makeText(this, "Hooray!",
Toast.LENGTH_LONG).show();
}
public void booToast() {
Toast.makeText(this, "Boo!",
Toast.LENGTH_LONG).show();
}
public void toggleInvalidText() {
if (mInvalidLoginText.getVisibility() == View.VISIBLE) {
mInvalidLoginText.setVisibility(View.INVISIBLE);
} else {
mInvalidLoginText.setVisibility(View.VISIBLE);
}
}
public boolean APICall(String url) throws JSONException{
// unnecessary finagling Android Studio suggested
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
// alertUserAboutError();
Log.e(TAG, "Exception caught:", e);
}
@Override
public void onResponse(Response response) throws IOException {
try {
mJSONData = response.body().string();
Log.v(TAG,response.body().string());
Log.v(TAG, mJSONData);
if (response.isSuccessful()) {
// Signal that response was successful
} else {
// alertUserAboutError();
}
}
catch (IOException e) {
Log.e(TAG, "Exception caught:", e);
}
}
});
if (mJSONData != null) return true;
else return false;
}
}
,返回的JSON应如下: “嘘”
{"logIn":true,"id":"5","userType":"1"}
总之,每当我与onClickListener(),我得到的点击按钮Toast弹出窗口,但几乎直接在logcat中,我看到我收到了JSON,当我在将mJSONData设置为null之前放置一个断点时,第一次按下按钮时什么都没有,但是在按下按钮第二次(并通过调试器循环)JSON现在已被存储到String中,之后它通常会导致我的应用程序崩溃(在将它煮沸并简单检查它是否为空之前)。
谢谢任何花时间和精力来帮助我理解到底发生了什么以及我能做些什么来改变它的人。
考虑使用改进与OkHttp一起:https://github.com/square/retrofit –