切换片段时,

时间:2019-11-10 17:54:53

标签: android android-fragments okhttp android-runonuithread

我没有接受过正规的编码教育,所以请告诉我我做过的事情是否被认为是不好的编码

我正在为正在制作的火车时刻表应用程序使用底部导航视图。选项之一是“附近”功能-在底部导航抽屉中单击“附近”时,将启动NearestFragment,并且我的服务器会自动通过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);

我还将上述内容以及OKHttp onSuccess和onFailure方法包装在if语句(getActivity!= null)中,以在继续操作之前检查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秒后但在加载完成之前从NeighborhoodFragment更改为另一个片段,我仍然会与带有NullPointerExceptions的onFailure方法相关联的崩溃,并且无法找到视图(例如小吃栏)。尝试/捕获中的onFailure可以捕获所有异常并忽略它们。感觉像是黑客,但是当通过底部导航从NearestFragment切换到另一个片段时,我的应用程序不再崩溃/无法正常工作。

@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块)组合的情况下阻止崩溃?

1 个答案:

答案 0 :(得分:1)

要了解活动或片段是否在UI上。

对于活动,您可以致电try: ... except: ... 对于片段呼叫isFinishing()

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

isAttached()