调用onResponse时应用程序崩溃

Far*_*day 0 java android stack-trace

我正在使用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);
    }


}
Run Code Online (Sandbox Code Playgroud)

如果应用程序启动而我不旋转它,它加载并解析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$4.onResponse(MainActivity.java:142)
                                                                         at com.example.poster.MainActivity$4.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)
Run Code Online (Sandbox Code Playgroud)

从堆栈跟踪,线142是progressDialog.dismiss();和线137new Response.Listener<JSONArray>() {

知道可能导致这个问题的原因及其解决方案吗?

更新:我正在考虑对其进行编码,因此只有在第一次创建应用程序时才会调用getData().这是因为,在配置更改后重新创建活动时会调用getData()(在本例中为rotation).所以这会导致活动重新加载.这可能吗?即仅在第一次调用getData()时,将创建活动.

Roh*_*rya 5

当app旋转时,activity会重新创建.现在你有了实例ProgressDialog progressDialog.因此,当活动旋转时,旧活动被破坏,因此该实例progressDialog被破坏.

现在,任务在后台线程上运行,当它返回时,它找不到,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();
Run Code Online (Sandbox Code Playgroud)

onResponse回调中:

if(progressDialog!=null){
    progressDialog.hide();
}
Run Code Online (Sandbox Code Playgroud)

onDestroy 活动:

if(progressDialog!=null) progressDialog.dismiss(); // to prevent memory leak
Run Code Online (Sandbox Code Playgroud)