一切正常。但我正在加载问题片段并立即单击返回并退出应用程序而不让请求完成。它崩溃了应用程序。我试着环顾四周,但找不到能帮我防止崩溃的修复方法。我正在附加logcat
和Questions
类供参考。
12-11 15:37:44.898 16772-16835/com.aftertutor.app E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
Process: com.aftertutor.app, PID: 16772
java.lang.NullPointerException
at com.aftertutor.app.Question$1.onResponse(Question.java:112)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
package com.aftertutor.app;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.aftertutor.app.model.API;
import com.dpizarro.autolabel.library.AutoLabelUI;
import com.dpizarro.autolabel.library.AutoLabelUISettings;
import com.github.thunder413.datetimeutils.DateTimeStyle;
import com.github.thunder413.datetimeutils.DateTimeUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.Date;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class Question extends Fragment {
public String id;
public TextView title;
public TextView desc;
public TextView date;
public TextView edit;
public TextView report;
public TextView username;
public AutoLabelUI tags;
public CardView cardView;
public ProgressBar progressBar;
public TextView votes;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_question, null);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
// Equivalent to on Create
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("Loading...");
title = view.findViewById(R.id.ques_title);
desc = view.findViewById(R.id.ques_desc);
date = view.findViewById(R.id.ques_time);
edit = view.findViewById(R.id.ques_edit);
report = view.findViewById(R.id.ques_report);
username = view.findViewById(R.id.ques_username);
tags = view.findViewById(R.id.ques_labels);
cardView = view.findViewById(R.id.ques_card);
progressBar = view.findViewById(R.id.ques_progress);
votes = view.findViewById(R.id.ques_votes);
Bundle arg = getArguments();
if (arg != null && arg.containsKey("id")) {
id = arg.getString("id");
}
loadQuestion(id);
}
public void loadQuestion(String qid) {
final API api = new API();
OkHttpClient client = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add("qid", qid)
.build();
Request request = api.call("get_question", body, getContext(), getActivity());
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
call.cancel();
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
MaterialDialog dialog = api.prepareDialog(getContext(), "An Error Occoured", "An Error Occoured. Please make sure you are connected to the internet and try again. If the issue still persists please contact support.");
dialog.show();
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseText = response.body().string();
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
try {
JSONObject jsonObject = new JSONObject(responseText);
if (jsonObject.get("status").equals("ok"))
{
JSONObject payload = jsonObject.getJSONObject("payload");
JSONObject questionItem = payload.getJSONObject("question");
title.setText(questionItem.get("title").toString());
getActivity().setTitle(questionItem.get("title").toString());
desc.setText(questionItem.get("description").toString());
date.setText(DateTimeUtils.getTimeAgo(getContext(), new Date(questionItem.getInt("postedOn") * 1000L), DateTimeStyle.AGO_FULL_STRING));
votes.setText(questionItem.getInt("votes") + "");
username.setText("@" + questionItem.get("postedBy").toString());
String[] taggs = api.toStringArray(questionItem.getJSONArray("tags"));
edit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Edit Page here
}
});
report.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MaterialDialog dialog = new MaterialDialog.Builder(getContext())
.title("Report this question because...")
.items(R.array.report_array)
.itemsCallbackSingleChoice(0, new MaterialDialog.ListCallbackSingleChoice() {
@Override
public boolean onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) {
Toast.makeText(getContext(), "YOU SELECTED: " + which, Toast.LENGTH_SHORT).show();
return false;
}
})
.content("Reporting will let us know that something isn't wrong with this post. We will take action asap.")
.positiveText("Report")
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
Toast.makeText(getContext(), "Reported", Toast.LENGTH_SHORT).show();
}
})
.negativeText("Cancel")
.build();
dialog.show();
}
});
AutoLabelUISettings autoLabelUISettings = new AutoLabelUISettings.Builder()
.withMaxLabels(5)
.withShowCross(false)
.withLabelsClickables(false)
.withBackgroundResource(R.drawable.rounded_corner)
.withTextSize(R.dimen.custom_label_font_size)
.withLabelPadding(R.dimen.custom_label_font_padding)
.build();
tags.setSettings(autoLabelUISettings);
tags.clear();
for (String tag: taggs) {
tags.addLabel(tag);
}
progressBar.setVisibility(View.GONE);
cardView.setVisibility(View.VISIBLE);
}
else if (jsonObject.get("status").equals("error"))
{
MaterialDialog dialog = api.prepareDialog(getContext(), jsonObject.getJSONObject("dialog").get("title").toString(), jsonObject.getJSONObject("dialog").get("message").toString());
dialog.show();
}
else
{
MaterialDialog dialog = api.prepareDialog(getContext(), "An Error Occurred", "An Error Occurred. Please make sure you are connected to the internet and try again. If the issue still persists please contact support.");
dialog.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
});
}
}
答案 0 :(得分:1)
您必须取消onPause()
中的来电,因此请拨打电话:
private Call call;
然后将您的loadQuestion()
方法更改为:
call = client.newCall(request);
call.enqueue(new Callback() {
取消请求:
@Override
public void onPause() {
super.onPause();
if (call != null){
call.cancel();
}
}
答案 1 :(得分:0)
由于您确定如果Exception
暂停,请求的响应会导致应用(Fragment
)崩溃,那么您可以在类中声明boolean
,如:
private boolean active= true;
然后在onResume
:
@Override
public void onResume() {
super.onResume();
active= true;
}
然后在onPause
@Override
public void onPause() {
super.onPause();
active= false;
}
然后在你片段的电话onResponse
中添加if
声明:
@Override
public void onResponse(Call call, Response response) throws IOException {
if(active){
//Call your extra code here!
}
}