【问题标题】:App Crashing When Replacing Fragment Before WebView Loads在 WebView 加载之前替换 Fragment 时应用程序崩溃
【发布时间】:2014-12-02 13:18:24
【问题描述】:

我的应用程序使用导航抽屉并在抽屉中进行选择时替换我的主要活动上的片段。我有几个显示 Web 视图的片段。如果我在 web 视图中的页面完成加载之前打开抽屉并选择不同的项目,从而用 web 视图替换片段,则会出现问题。发生这种情况时,我收到此错误:

12-02 08:07:48.605  11745-11745/kyfb.android.kyfb.com.kyfb A/chromium﹕ [FATAL:jni_android.cc(271)] Check failed: false.
12-02 08:07:48.605  11745-11745/kyfb.android.kyfb.com.kyfb A/libc﹕ Fatal signal 6 (SIGABRT), code -6 in tid 11745 (d.kyfb.com.kyfb)

这是带有 web 视图的片段之一。

public class AnnualMeetingFragment extends Fragment {

    private WebView web;
    private ProgressBar progressBar;

    private String url;

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View rootView = inflater.inflate(R.layout.fragment_ag_facts, null);

        url = "http://www.kyfbnewsroom.com/2013-kentucky-farm-bureau-annual-meeting-program/";

        web = (WebView)rootView.findViewById(R.id.web);
        progressBar = (ProgressBar)rootView.findViewById(R.id.prgPageLoading);

        web.getSettings().setDomStorageEnabled(true);
        web.getSettings().setJavaScriptEnabled(true);
        web.getSettings().setSupportZoom(true);
        web.getSettings().setBuiltInZoomControls(true);
        web.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
        web.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
        web.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);

        web.loadUrl(url);

        web.setWebChromeClient(new WebChromeClient() {
            public void onProgressChanged(WebView webView, int progress) {
                getActivity().setProgress(progress * 100);
                progressBar.setProgress(progress);
            }
        });

        web.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(web, url, favicon);
                progressBar.setVisibility(View.VISIBLE);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(web, url);
                progressBar.setProgress(0);
                progressBar.setVisibility(View.GONE);
            }

            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                Toast.makeText(getActivity(), description, Toast.LENGTH_SHORT).show();
            }

            public boolean shouldOverrideUrlLoading(WebView view, String url)
            {


                if(url.endsWith(".mp4") || url.endsWith(".3gp") || url.endsWith(".avi") || url.endsWith(".flv")){
                    Intent i = new Intent(Intent.ACTION_VIEW);
                    i.setData(Uri.parse(url));
                    startActivity(i); //warning no error handling will cause force close if no media player on phone.
                    return true;
                }

                view.loadUrl(url);
                return true;
            }
        });

        return rootView;
    }
}

【问题讨论】:

  • webview 是一个片段?
  • 你能用你的 webView 给我们代码吗?
  • 删除super.onCreateView(...)后会发生什么?
  • @Randy,删除它似乎并没有改变它。

标签: java android android-fragments webview


【解决方案1】:

我不确定您为什么会收到此错误,我认为它应该类似于 NullPointerException。 接下来试试: Evert 当你在 Fragment 实例上调用 getActivity() 时,你应该确定,该 Fragment 实际上有这个 Activity。因为当你的 webview 正在加载时,你正在调用这个函数:

web.setWebChromeClient(new WebChromeClient() {
        public void onProgressChanged(WebView webView, int progress) {
            getActivity().setProgress(progress * 100);
            progressBar.setProgress(progress);
        }
    });

我认为你应该将你调用 getActivity() 的所有代码替换为这样的:

Activity activity = getActivity();
if (activity != null) {
    // do something
}

试试这个,告诉我这是否有效。

【讨论】:

  • 如果是 NullPointerException,堆栈跟踪会显示 NullPonterException。致命信号与 WebView 中发生的事情有关。可能与调用某个函数时webview的状态有关。例如,请参阅我的问题 (stackoverflow.com/questions/18755318/…)。在销毁所有 WebView 后调用 WebStorage.getInstance().deleteAllData() 时,我收到了致命信号。我猜这个人也有类似的问题。
【解决方案2】:

您应该在分离片段时销毁 webview。

从片段的分离方法调用 webview.destroy()。

【讨论】:

    【解决方案3】:

    FragmentManager 可能会保留您可以通过标签键检索的旧片段。 进入具有正在执行替换的 FragmentManager 的活动。 进行替换时,使用标签来识别片段。在进行替换之前,请检查片段管理器是否已经有一个带有该标签的片段并使用该标签而不是创建一个新的片段实例。您的片段事务应如下所示:

    String fragTag = "FRAGMENT_1"; //Should be a class constant 
    FragmentManager fm = getFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    Fragment fragment = fm.findFragmentByTag(fragTag);
    if(fragment == null) {
        fragment = new AnnualMeetingFragment();
    }
    ft.replace(R.id.container, fragment, fragTag);
    ft.commit();
    

    此外,WebViewClient 实现中的“onReceivedError”可能会在 Fragment 未实际附加到活动时发生。所以 getActivity() 可能不会在那里返回有效值。

    【讨论】:

      猜你喜欢
      • 2020-04-19
      • 1970-01-01
      • 1970-01-01
      • 2012-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-11
      • 1970-01-01
      相关资源
      最近更新 更多