简体   繁体   English

空指针异常:createProgressDialog

[英]NullPointerException: createProgressDialog

Get next error from Crashlytics for Android version: 10 :从 Crashlytics for Android version: 10获取下一个错误Android version: 10

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
       at android.app.Dialog.<init>(Dialog.java:196)
       at android.app.ColorBaseAlertDialog.<init>(ColorBaseAlertDialog.java:33)
       at android.app.AlertDialog.<init>(AlertDialog.java:208)
       at android.app.AlertDialog.<init>(AlertDialog.java:204)
       at android.app.ProgressDialog.<init>(ProgressDialog.java:112)
       at com.sau.authenticator.widget.fragment.BaseFragment.createProgressDialog(BaseFragment.java:46)
       at com.sau.authenticator.widget.fragment.BaseFragment.showLoadProgress(BaseFragment.java:41)
       at com.sau.authenticator.widget.fragment.WebViewFragment$webViewClient$1.onPageStarted(WebViewFragment.java:69)
       at i6.c(i6.java:2)
       at Hn.handleMessage(Hn.java:145)
       at android.os.Handler.dispatchMessage(Handler.java:107)
       at android.os.Looper.loop(Looper.java:228)
       at android.app.ActivityThread.main(ActivityThread.java:7782)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:981)

In my function createProgressDialog , which is called in BaseFragment:在我的函数createProgressDialog ,它在 BaseFragment 中调用:

abstract class BaseFragment : Fragment() {
    private var progressDialog: ProgressDialog? = null
    val activityComponents: ActivityComponentsContract?
        get() = activity?.activityComponentsContract

    override fun onDestroy() {
        progressDialog?.dismiss()
        progressDialog = null
        super.onDestroy()
    }

    protected fun showLoadProgress() {
        if (progressDialog == null) progressDialog = createProgressDialog()
        progressDialog?.show()
    }

    private fun createProgressDialog(): ProgressDialog? {
        val dialog = ProgressDialog(activity, R.style.ProgressDialogTheme)
        dialog.setCancelable(false)
        dialog.setProgressStyle(android.R.style.Widget_ProgressBar_Large)
        return dialog
    }

    protected fun dismissLoadProgress() {
        progressDialog?.dismiss()
    }
}

Here is code of my WebViewFragment:这是我的 WebViewFragment 的代码:

class WebViewFragment : BaseFragment() {

    private var url = ""
    private var title = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            url = it.getString(KEY_URL, "")
            title = it.getString(KEY_TITLE, "")
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        activityComponents?.updateAppbar(
            title = title,
            backActionImageResId = R.drawable.ic_appbar_action_back
        )
        return inflater.inflate(R.layout.fragment_web_view, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        customWebView?.webViewClient = webViewClient
        customWebView?.loadUrl(url)
    }

    private val webViewClient = object : WebViewClient() {

        override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
            super.onPageStarted(view, url, favicon)
            showLoadProgress()
        }

        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
            dismissLoadProgress()
        }
    }

    companion object {
        const val KEY_URL = "KEY_URL"

        fun newBundle(url: String = "", title: String): Bundle {
            return Bundle().apply {
                putString(KEY_URL, url)
                putString(KEY_TITLE, title)
            }
        }
    }
}

I'm not too familiar with WebView , but it seems like by the time onPageStarted() is called your user already navigated away (or rotated his device).我对WebView不太熟悉,但是当onPageStarted()被调用时,您的用户似乎已经导航离开(或旋转了他的设备)。 Hence your Fragment 's onDestroyView() is likely called already, but you are not notifying your WebView that starts loading your url.因此您的FragmentonDestroyView()可能已经被调用,但您没有通知您的WebView开始加载您的 url。 That's why activity is null and you get the exception.这就是为什么activitynull并且您得到异常的原因。

So on your WebViewFragment 's lifecycle callbacks make sure you notify your WebView too:因此,在您的WebViewFragment的生命周期回调中,请确保您也通知您的WebView

override fun onResume() {
    super.onResume()
    customWebView?.onResume()
}

override fun onPause() {
    super.onPause()
    customWebView?.onPause()
}

override fun onDestroyView() {
    super.onDestroyView()
    customWebView?.stopLoading() // this should prevent onPageStarted() from being called
}

It seems that this error happened when your Fragment was DestroyView.当您的 Fragment 是 DestroyView 时,似乎发生了此错误。 I am not entirely sure about this.我不完全确定这一点。 You can reproduce by load a large web page, then navigate to another fragment so that WebViewFragment / onViewDestroyed is executed.您可以通过加载一个大网页来重现,然后导航到另一个片段,以便执行 WebViewFragment / onViewDestroyed。 Print logs in onPageStarted and onPageFinished.在 onPageStarted 和 onPageFinished 中打印日志。 If you see them being called when you destroy the view, this is exactly the cause.如果您在销毁视图时看到它们被调用,这正是原因。 At this point you just need to check the lifecycle state to show or hide progress.此时您只需要检查生命周期状态以显示或隐藏进度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM