调用 onResponse 时应用程序崩溃
App crashes when onResponse is called
我正在使用 volley 加载 JSON 数据。
这是 MainActivity
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private final String TAG = "MainActivity";
//Creating a list of posts
private List<PostItems> mPostItemsList;
//Creating Views
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "Device rotated and onCreate called");
//Initializing Views
recyclerView = (RecyclerView) findViewById(R.id.post_recycler);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//Initializing the postlist
mPostItemsList = new ArrayList<>();
adapter = new PostAdapter(mPostItemsList, this);
recyclerView.setAdapter(adapter);
if (NetworkCheck.isAvailableAndConnected(this)) {
//Caling method to get data
getData();
} else {
final Context mContext;
mContext = this;
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("No Internet Connection");
alertDialogBuilder.setMessage("Failed to load. Please ensure you're connected to the internet and try again.");
alertDialogBuilder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (!NetworkCheck.isAvailableAndConnected(mContext)) {
alertDialogBuilder.show();
} else {
getData();
}
}
});
alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alertDialogBuilder.show();
}
}
//This method will get data from the web api
private void getData(){
Log.d(TAG, "getData called");
//Showing progress dialog
final ProgressDialog progressDialog = ProgressDialog.show(this, null, "Loading posts", false, false);
//Creating a json request
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigPost.GET_URL,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, "onResponse called");
//Dismissing the progress dialog
progressDialog.dismiss();
//calling method to parse json array
parseData(response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
//Creating request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(jsonArrayRequest);
}
}
如果应用程序启动并且我没有旋转它,它会加载并解析 JSON 非常好;但是如果应用程序启动并且我多次旋转设备,应用程序会在调用 onResponse
后立即崩溃。
这是堆栈跟踪
04-03 12:46:10.493 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called
04-03 12:46:10.493 22221-22221/com.example.poster D/MainActivity: getData called
04-03 12:46:11.234 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called
04-03 12:46:11.234 22221-22221/com.example.poster D/MainActivity: getData called
04-03 12:46:12.675 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called
04-03 12:46:12.685 22221-22221/com.example.poster D/MainActivity: getData called
04-03 12:46:14.096 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called
04-03 12:46:14.096 22221-22221/com.example.poster D/MainActivity: getData called
04-03 12:46:15.278 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called
04-03 12:46:15.288 22221-22221/com.example.poster D/MainActivity: getData called
04-03 12:46:15.448 22221-22221/com.example.poster D/MainActivity: onResponse called
04-03 12:46:15.448 22221-22221/com.example.poster E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.poster, PID: 22221
java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{7873bab V.E..... R......D 0,0-480,174} not attached to window manager
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:396)
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:322)
at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:116)
at android.app.Dialog.dismissDialog(Dialog.java:341)
at android.app.Dialog.dismiss(Dialog.java:324)
at com.example.poster.MainActivity.onResponse(MainActivity.java:142)
at com.example.poster.MainActivity.onResponse(MainActivity.java:137)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
从堆栈跟踪来看,第 142 行是 progressDialog.dismiss();
,第 137 行是 new Response.Listener<JSONArray>() {
知道是什么原因造成的吗?
更新:我正在考虑对其进行编码,以便仅在首次创建应用程序时调用 getData()。这是因为,在配置更改(在本例中为旋转)后重新创建 activity 时,将调用 getData()。所以这会导致 activity 重新加载。这可能吗? IE。仅在第一次调用 getData() 时,会创建 activity。
您只需要在关闭 progressdialog
时检查对象 null
。
ProgressDialog progressDialog = ProgressDialog.show(this, null, "Loading posts", false, false);
if(progressDialog!=null)
progressDialog.dismiss();
当应用旋转时,activity
被重新创建。现在你已经得到了 ProgressDialog
progressDialog
的实例。所以当 activity 旋转时,旧的 activity 被销毁,因此这个实例 progressDialog
被销毁。
现在,任务在后台线程上 运行,当它 returns 时,它找不到 progressDialog
,因为它已被销毁,因此当前 not attached to window manager
(IllegalArgumentException
).
所以最好在访问实例 progressDialog
之前检查它 onResponse
。
尝试像这样使用 ProgressDialog
:
定义一个全局实例:
private ProgressDialog progressDialog;
在getData
方法中:
private void getData(){
Log.d(TAG, "getData called");
//Showing progress dialog
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Loading posts");
progressDialog.show();
在onResponse
回调中:
if(progressDialog!=null){
progressDialog.hide();
}
onDestroy
共 activity:
if(progressDialog!=null) progressDialog.dismiss(); // to prevent memory leak
我正在使用 volley 加载 JSON 数据。
这是 MainActivity
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private final String TAG = "MainActivity";
//Creating a list of posts
private List<PostItems> mPostItemsList;
//Creating Views
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "Device rotated and onCreate called");
//Initializing Views
recyclerView = (RecyclerView) findViewById(R.id.post_recycler);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//Initializing the postlist
mPostItemsList = new ArrayList<>();
adapter = new PostAdapter(mPostItemsList, this);
recyclerView.setAdapter(adapter);
if (NetworkCheck.isAvailableAndConnected(this)) {
//Caling method to get data
getData();
} else {
final Context mContext;
mContext = this;
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("No Internet Connection");
alertDialogBuilder.setMessage("Failed to load. Please ensure you're connected to the internet and try again.");
alertDialogBuilder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (!NetworkCheck.isAvailableAndConnected(mContext)) {
alertDialogBuilder.show();
} else {
getData();
}
}
});
alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alertDialogBuilder.show();
}
}
//This method will get data from the web api
private void getData(){
Log.d(TAG, "getData called");
//Showing progress dialog
final ProgressDialog progressDialog = ProgressDialog.show(this, null, "Loading posts", false, false);
//Creating a json request
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigPost.GET_URL,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, "onResponse called");
//Dismissing the progress dialog
progressDialog.dismiss();
//calling method to parse json array
parseData(response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
//Creating request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(jsonArrayRequest);
}
}
如果应用程序启动并且我没有旋转它,它会加载并解析 JSON 非常好;但是如果应用程序启动并且我多次旋转设备,应用程序会在调用 onResponse
后立即崩溃。
这是堆栈跟踪
04-03 12:46:10.493 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called
04-03 12:46:10.493 22221-22221/com.example.poster D/MainActivity: getData called
04-03 12:46:11.234 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called
04-03 12:46:11.234 22221-22221/com.example.poster D/MainActivity: getData called
04-03 12:46:12.675 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called
04-03 12:46:12.685 22221-22221/com.example.poster D/MainActivity: getData called
04-03 12:46:14.096 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called
04-03 12:46:14.096 22221-22221/com.example.poster D/MainActivity: getData called
04-03 12:46:15.278 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called
04-03 12:46:15.288 22221-22221/com.example.poster D/MainActivity: getData called
04-03 12:46:15.448 22221-22221/com.example.poster D/MainActivity: onResponse called
04-03 12:46:15.448 22221-22221/com.example.poster E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.poster, PID: 22221
java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{7873bab V.E..... R......D 0,0-480,174} not attached to window manager
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:396)
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:322)
at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:116)
at android.app.Dialog.dismissDialog(Dialog.java:341)
at android.app.Dialog.dismiss(Dialog.java:324)
at com.example.poster.MainActivity.onResponse(MainActivity.java:142)
at com.example.poster.MainActivity.onResponse(MainActivity.java:137)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
从堆栈跟踪来看,第 142 行是 progressDialog.dismiss();
,第 137 行是 new Response.Listener<JSONArray>() {
知道是什么原因造成的吗?
更新:我正在考虑对其进行编码,以便仅在首次创建应用程序时调用 getData()。这是因为,在配置更改(在本例中为旋转)后重新创建 activity 时,将调用 getData()。所以这会导致 activity 重新加载。这可能吗? IE。仅在第一次调用 getData() 时,会创建 activity。
您只需要在关闭 progressdialog
时检查对象 null
。
ProgressDialog progressDialog = ProgressDialog.show(this, null, "Loading posts", false, false);
if(progressDialog!=null)
progressDialog.dismiss();
当应用旋转时,activity
被重新创建。现在你已经得到了 ProgressDialog
progressDialog
的实例。所以当 activity 旋转时,旧的 activity 被销毁,因此这个实例 progressDialog
被销毁。
现在,任务在后台线程上 运行,当它 returns 时,它找不到 progressDialog
,因为它已被销毁,因此当前 not attached to window manager
(IllegalArgumentException
).
所以最好在访问实例 progressDialog
之前检查它 onResponse
。
尝试像这样使用 ProgressDialog
:
定义一个全局实例:
private ProgressDialog progressDialog;
在getData
方法中:
private void getData(){
Log.d(TAG, "getData called");
//Showing progress dialog
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Loading posts");
progressDialog.show();
在onResponse
回调中:
if(progressDialog!=null){
progressDialog.hide();
}
onDestroy
共 activity:
if(progressDialog!=null) progressDialog.dismiss(); // to prevent memory leak