切换片段时 OKHttp 崩溃

OKHttp crashes on when switching Fragments

我没有接受过正规的编码教育,所以如果我做的事情被认为是糟糕的编码,请告诉我

我正在为我正在制作的火车时刻表应用程序使用底部导航视图。其中一个选项是附近的功能 - 当点击底部导航抽屉上的附近时,NearbyFragment 启动并且我的服务器通过 OKHttp 自动获得请求而无需额外的用户交互

问题是,如果您从“附近”切换到底部导航视图上的另一个按钮,或者如果您多次点击附近的按钮,应用程序就会崩溃。最初,这是因为 runOnUiThread 方法无法找到 UI 线程,因为我转到了另一个片段(并且可能主线程不再存在)。我尝试通过在 onViewCreated

中调用 getLocation 方法之前创建 1 秒延迟来解决此问题
// Delay before calling on location to prevent crashing when rapidly switching from Nearby Fragment
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (getActivity() != null) {
                    getLocation();
                }
            }
        }, 1000);

我还在 if 语句 (getActivity != null) 中包装了上述内容以及 OKHttp onSuccess 和 onFailure 方法,以在继续之前检查 UI 线程是否仍然存在

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    final String myResponse = response.body().string();
                    if (getActivity() != null) {
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                processJSON(myResponse);
                            }
                        });
                    }
                }
            }

如果我在加载 1 秒后但在加载完成之前从 NearbyFragment 更改为不同的片段,我仍然会遇到与带有 NullPointerExceptions 的 onFailure 方法相关的崩溃并且找不到视图(例如小吃店),所以我将 onFailure 包装在 try/catch 中以捕获所有异常并忽略它们。这感觉像是一个黑客,但当通过底部导航从 NearbyFragment 切换到另一个片段时,我的应用程序不再像预期的那样 crashes/acts。

@Override
            public void onFailure(Call call, IOException e) {
                try {
                    mSwipeToRefresh.setRefreshing(false);
                    Log.e("Main", e.toString());
                    mSnackbar = Snackbar.make(getActivity().findViewById(R.id.swipe_container_nearby), "ERROR!", Snackbar.LENGTH_INDEFINITE);
                    snackBarCoordinator(mSnackbar);
                    mSnackbar.show();
                } catch (Exception j) {
                    Log.e("Failed Get Closest Stations ", j.toString());
                }
            }

是否有清洁器可以在不结合三个故障保险即 handler.postDelayed、(getActivity() != null) 和空 try/catch 块的情况下阻止崩溃?

要知道 activity 或片段是否在 UI.

对于Activity,您可以调用isFinishing() 对于片段调用 isAttached().

即在显示加载器、小吃店或任何用 if(...) 包装的小部件之前 {}

if(isAttached()) { snackbar.show(); }