Android OkHttp 异步回调中的 SetText 导致崩溃
Android SetText in OkHttp Async callback causing crash
我有一个 android activity 执行异步 Okhttp 调用,当加载 activity 时(从 onStart
方法作为 getActiveRequests()).
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button btLogout;
UserLocalStore userLocalStore;
String username;
String userEmail;
String recentAppName;
String recentRequestTime;
String isExpired;
TelephonyManager telephonyManager;
OkHttpClient client;
TextView tvRecentAppName, tvRecentRequestTime, tvIsExpired;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userLocalStore = new UserLocalStore(this);
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
TextView tvUserName = (TextView) findViewById(R.id.userName);
TextView tvUserEmail = (TextView) findViewById(R.id.userEmail);
tvRecentAppName = (TextView) findViewById(R.id.recentAppName);
tvRecentRequestTime = (TextView) findViewById(R.id.recentRequestTime);
tvIsExpired = (TextView) findViewById(R.id.isExpired);
client = new OkHttpClient();
username = userLocalStore.getLoggedInUser().name;
userEmail = userLocalStore.getLoggedInUser().email;
tvUserEmail.setText(userEmail);
tvUserName.setText(username);
btLogout = (Button) findViewById(R.id.btLogout);
btLogout.setOnClickListener(this);
}
@Override
protected void onStart() {
super.onStart();
if(authenticateUser() == true){
getActiveRequests();
}else{
startActivity(new Intent(this, LoginActivity.class));
}
}
我想做的是在使用 SetText
方法进行 Http 调用后更新 UI。这是我的调用,在 GetActiveRequests() 方法中实现。
client.newCall(request)
.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
String hello = "failed call";
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseData = response.body().string();
if (responseData != null) {
Gson gson = new Gson();
JsonElement element = gson.fromJson(responseData, JsonElement.class);
JsonObject jsonObject = element.getAsJsonObject();
final AccessRequest request = gson.fromJson(jsonObject, AccessRequest.class);
recentAppName = request.AppName.toString();
recentRequestTime = request.RequestTime.toString();
if (request.IsExpired)
isExpired = "Has Expired";
else isExpired = "Active";
tvRecentAppName.setText(recentAppName);
tvRecentRequestTime.setText(recentRequestTime);
tvIsExpired.setText(isExpired);
}
}
});
我遇到的问题是,当调试器到达 SetText
行代码时,它会导致应用程序崩溃并关闭。我不知道如何解决这个问题,但我认为它与无法更新 UI 的 Okhttp Async
调用有关,因为我的 setText 方法在 [=17] 中工作正常=].
这是因为视图的更新只能在 UI 线程和 OkHttp 的 onResponse
运行 后台线程上完成。像这样在主线程上尝试 运行:
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseData = response.body().string();
if (responseData != null) {
Gson gson = new Gson();
JsonElement element = gson.fromJson(responseData, JsonElement.class);
JsonObject jsonObject = element.getAsJsonObject();
final AccessRequest request = gson.fromJson(jsonObject, AccessRequest.class);
recentAppName = request.AppName.toString();
recentRequestTime = request.RequestTime.toString();
if (request.IsExpired)
isExpired = "Has Expired";
else isExpired = "Active";
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
//Handle UI here
tvRecentAppName.setText(recentAppName);
tvRecentRequestTime.setText(recentRequestTime);
tvIsExpired.setText(isExpired);
}
});
}
}
同样,如果您在 onFailure
上更新了任何视图,请在 UI 线程上进行。
我有一个 android activity 执行异步 Okhttp 调用,当加载 activity 时(从 onStart
方法作为 getActiveRequests()).
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button btLogout;
UserLocalStore userLocalStore;
String username;
String userEmail;
String recentAppName;
String recentRequestTime;
String isExpired;
TelephonyManager telephonyManager;
OkHttpClient client;
TextView tvRecentAppName, tvRecentRequestTime, tvIsExpired;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userLocalStore = new UserLocalStore(this);
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
TextView tvUserName = (TextView) findViewById(R.id.userName);
TextView tvUserEmail = (TextView) findViewById(R.id.userEmail);
tvRecentAppName = (TextView) findViewById(R.id.recentAppName);
tvRecentRequestTime = (TextView) findViewById(R.id.recentRequestTime);
tvIsExpired = (TextView) findViewById(R.id.isExpired);
client = new OkHttpClient();
username = userLocalStore.getLoggedInUser().name;
userEmail = userLocalStore.getLoggedInUser().email;
tvUserEmail.setText(userEmail);
tvUserName.setText(username);
btLogout = (Button) findViewById(R.id.btLogout);
btLogout.setOnClickListener(this);
}
@Override
protected void onStart() {
super.onStart();
if(authenticateUser() == true){
getActiveRequests();
}else{
startActivity(new Intent(this, LoginActivity.class));
}
}
我想做的是在使用 SetText
方法进行 Http 调用后更新 UI。这是我的调用,在 GetActiveRequests() 方法中实现。
client.newCall(request)
.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
String hello = "failed call";
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseData = response.body().string();
if (responseData != null) {
Gson gson = new Gson();
JsonElement element = gson.fromJson(responseData, JsonElement.class);
JsonObject jsonObject = element.getAsJsonObject();
final AccessRequest request = gson.fromJson(jsonObject, AccessRequest.class);
recentAppName = request.AppName.toString();
recentRequestTime = request.RequestTime.toString();
if (request.IsExpired)
isExpired = "Has Expired";
else isExpired = "Active";
tvRecentAppName.setText(recentAppName);
tvRecentRequestTime.setText(recentRequestTime);
tvIsExpired.setText(isExpired);
}
}
});
我遇到的问题是,当调试器到达 SetText
行代码时,它会导致应用程序崩溃并关闭。我不知道如何解决这个问题,但我认为它与无法更新 UI 的 Okhttp Async
调用有关,因为我的 setText 方法在 [=17] 中工作正常=].
这是因为视图的更新只能在 UI 线程和 OkHttp 的 onResponse
运行 后台线程上完成。像这样在主线程上尝试 运行:
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseData = response.body().string();
if (responseData != null) {
Gson gson = new Gson();
JsonElement element = gson.fromJson(responseData, JsonElement.class);
JsonObject jsonObject = element.getAsJsonObject();
final AccessRequest request = gson.fromJson(jsonObject, AccessRequest.class);
recentAppName = request.AppName.toString();
recentRequestTime = request.RequestTime.toString();
if (request.IsExpired)
isExpired = "Has Expired";
else isExpired = "Active";
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
//Handle UI here
tvRecentAppName.setText(recentAppName);
tvRecentRequestTime.setText(recentRequestTime);
tvIsExpired.setText(isExpired);
}
});
}
}
同样,如果您在 onFailure
上更新了任何视图,请在 UI 线程上进行。