当 getView() 为 null 时,即 onCreateView() 之前或 onDestroyView() 之后,无法访问 Fragment View 的 LifecycleOwner

Apo*_*ava 3 android android-lifecycle android-fragments kotlin lifecycleowner

我的应用程序中有一个名为 HomeFragment 的片段。以下是它的代码:

\n
import android.Manifest\nimport android.app.Activity\nimport android.app.AlertDialog\nimport android.content.Intent\nimport android.content.pm.PackageManager\nimport androidx.lifecycle.ViewModelProvider\nimport android.os.Bundle\nimport androidx.fragment.app.Fragment\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.core.content.ContextCompat\nimport androidx.fragment.app.viewModels\nimport androidx.lifecycle.Observer\nimport com.example.weatherapp.R\nimport com.example.weatherapp.WeatherApplication\nimport com.example.weatherapp.utils.GPS_REQUEST_CHECK_SETTINGS\nimport com.example.weatherapp.utils.GpsUtil\nimport com.example.weatherapp.utils.SharedPreferenceHelper\nimport com.example.weatherapp.utils.observeOnce\nimport com.google.android.material.snackbar.Snackbar\nimport kotlinx.android.synthetic.main.home_fragment.view.*\n\nclass HomeFragment : Fragment() {\n\n    private lateinit var homeView: View\n    private var isGPSEnabled = false\n    private lateinit var prefs: SharedPreferenceHelper\n\n    private val viewModel by viewModels<HomeViewModel> {\n        HomeViewModel.HomeFragmentViewModelFactory(\n            (requireContext().applicationContext as WeatherApplication).weatherRepository,\n            requireActivity().application\n        )\n    }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        prefs = SharedPreferenceHelper.getInstance(requireContext())\n        GpsUtil(requireContext()).turnGPSOn(object : GpsUtil.OnGpsListener {\n            override fun gpsStatus(isGPSEnabled: Boolean) {\n                this@HomeFragment.isGPSEnabled = isGPSEnabled\n            }\n        })\n    }\n    override fun onStart() {\n        super.onStart()\n        invokeLocationAction()\n    }\n\n    private fun invokeLocationAction() {\n        when {\n            allPermissionsGranted() -> {\n                viewModel.getLocationLiveData().observeOnce(\n                    viewLifecycleOwner,\n                    Observer { location ->\n                        if (location != null) {\n                            viewModel.getWeather(location)\n                        }\n                    }\n                )\n            }\n\n            shouldShowRequestPermissionRationale() -> {\n                AlertDialog.Builder(requireContext())\n                    .setTitle("Location Permission")\n                    .setMessage("This application requires access to your location to function!")\n                    .setNegativeButton("No") { _, _ -> requireActivity().finish() }\n                    .setPositiveButton("Ask me") { _, _ ->\n                        requestPermissions(REQUIRED_PERMISSIONS, LOCATION_REQUEST_CODE)\n                    }\n                    .show()\n            }\n\n            !isGPSEnabled -> {\n                Snackbar.make(\n                    homeView.root,\n                    "GPS is required for this application to function!",Snackbar.LENGTH_SHORT\n                ).show()\n            }\n\n            else -> {\n                requestPermissions(REQUIRED_PERMISSIONS, LOCATION_REQUEST_CODE)\n            }\n        }\n    }\n\n    override fun onCreateView(\n        inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?\n    ): View? {\n        homeView =  inflater.inflate(R.layout.home_fragment, container, false)\n        return view;\n    }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        when (requestCode) {\n            Activity.RESULT_OK -> {\n                when (requestCode) {\n                    GPS_REQUEST_CHECK_SETTINGS -> {\n                        isGPSEnabled = true\n                        invokeLocationAction()\n                    }\n                }\n            }\n\n            Activity.RESULT_CANCELED -> {\n                when (requestCode) {\n                    GPS_REQUEST_CHECK_SETTINGS -> {\n                        Snackbar.make(\n                            homeView.root,"Enable your GPS and restart!",Snackbar.LENGTH_LONG\n                        ).show()\n                    }\n                }\n            }\n        }\n    }\n\n    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {\n        ContextCompat.checkSelfPermission(requireContext(), it) == PackageManager.PERMISSION_GRANTED\n    }\n\n    private fun shouldShowRequestPermissionRationale() = REQUIRED_PERMISSIONS.all {\n        shouldShowRequestPermissionRationale(it)\n    }\n\n    override fun onRequestPermissionsResult(\n        requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {\n        super.onRequestPermissionsResult(requestCode, permissions, grantResults)\n        if (requestCode == LOCATION_REQUEST_CODE) {\n            invokeLocationAction()\n        }\n    }\n\n    companion object {\n        private val REQUIRED_PERMISSIONS = arrayOf(\n            Manifest.permission.ACCESS_FINE_LOCATION,\n            Manifest.permission.ACCESS_COARSE_LOCATION\n        )\n        private const val LOCATION_REQUEST_CODE = 123\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

该应用程序编译成功。但当我在设备上打开它时,应用程序崩溃了。\n这是我在运行应用程序时在 logcat 中遇到的错误:

\n
2021-05-25 17:45:25.968 32061-32061/com.example.weatherapp D/NetworkSecurityConfig: No Network Security Config specified, using platform default\n2021-05-25 17:45:25.989 32061-32061/com.example.weatherapp D/AndroidRuntime: Shutting down VM\n    \n    \n    --------- beginning of crash\n2021-05-25 17:45:25.997 32061-32061/com.example.weatherapp E/AndroidRuntime: FATAL EXCEPTION: main\n    Process: com.example.weatherapp, PID: 32061\n    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.weatherapp/com.example.weatherapp.ui.MainActivity}: java.lang.IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView()\n        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2949)\n        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3027)\n        at android.app.ActivityThread.-wrap11(Unknown Source:0)\n        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1745)\n        at android.os.Handler.dispatchMessage(Handler.java:106)\n        at android.os.Looper.loop(Looper.java:200)\n        at android.app.ActivityThread.main(ActivityThread.java:6956)\n        at java.lang.reflect.Method.invoke(Native Method)\n        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:519)\n        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:836)\n     Caused by: java.lang.IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView()\n        at androidx.fragment.app.Fragment.getViewLifecycleOwner(Fragment.java:361)\n        at com.example.weatherapp.ui.home.HomeFragment.invokeLocationAction(HomeFragment.kt:57)\n        at com.example.weatherapp.ui.home.HomeFragment.onStart(HomeFragment.kt:50)\n        at androidx.fragment.app.Fragment.performStart(Fragment.java:3021)\n        at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:589)\n        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:300)\n        at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)\n        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)\n        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)\n        at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:3079)\n        at androidx.fragment.app.FragmentController.dispatchStart(FragmentController.java:262)\n        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:510)\n        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)\n        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1335)\n        at android.app.Activity.performStart(Activity.java:7245)\n        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2912)\n        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3027)\xc2\xa0\n        at android.app.ActivityThread.-wrap11(Unknown Source:0)\xc2\xa0\n        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1745)\xc2\xa0\n        at android.os.Handler.dispatchMessage(Handler.java:106)\xc2\xa0\n        at android.os.Looper.loop(Looper.java:200)\xc2\xa0\n        at android.app.ActivityThread.main(ActivityThread.java:6956)\xc2\xa0\n        at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:519)\xc2\xa0\n        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:836)\xc2\xa0\n2021-05-25 17:45:26.014 32061-32061/com.example.weatherapp I/Process: Sending signal. PID: 32061 SIG: 9\n
Run Code Online (Sandbox Code Playgroud)\n

我假设我尝试在错误的位置访问片段视图的生命周期所有者。请帮我解决这个问题。

\n

ian*_*ake 6

您onCreateView()没有返回刚刚夸大的视图。这意味着您的 Fragment 视图为 null 并且viewLifecycleOwner确实无效。

您应该更改您的onCreateView以返回新膨胀的视图:

override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        homeView = inflater.inflate(R.layout.home_fragment, container, false)
        return homeView
    }
Run Code Online (Sandbox Code Playgroud)