未调用 Fragment 的 onCreateView()

Fragment's onCreateView() is not being called

提问人:Dylon Jaynes 提问时间:4/6/2022 最后编辑:Dylon Jaynes 更新时间:4/6/2022 访问量:628

问:

我正在创建我的片段的一个实例,然后尝试调用它的方法之一,但需要在 onCreateView() 中实例化一个变量,然后才能在不抛出 NullPointerException 的情况下调用该方法。

这是我的部分片段:

class UpdatesFragment : androidx.fragment.app.Fragment(){

var progressBar: ProgressBar? = null
private var instance: UpdatesFragment? = null
private var application: CustomApplication? = null
var bluetoothManager2: BluetoothManager? = null
private lateinit var li: LayoutInflater
private var deviceContainer: ViewFlipper? = null
private var devicePrep: View? = null
private var progressLayout: View? = null
private var progressText: TextView? = null
var progressBarText: TextView? = null
var progressChunk: TextView? = null
private var scroll: ScrollView? = null
private var logWindow: TextView? = null
private var currentView = 0
private var disconnected = false

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
View? {

instance = this
application = activity?.application as CustomApplication
if (bluetoothManager2 == null) {
bluetoothManager2 = SuotaManager() // THIS LINE NEEDS TO BE CALLED BEFORE MY METHOD IS CALLED. 
>         }
bluetoothManager2!!.setContext(this)
bluetoothManager2!!.setDevice(application!!.device)

progressText = progressLayout!!.findViewById(R.id.progress_text)
progressChunk = progressLayout!!.findViewById(R.id.progress_chunk)
progressBar = progressLayout!!.findViewById(R.id.progress_bar)
progressBarText = progressLayout!!.findViewById(R.id.progress_bar_text)
scroll = progressLayout!!.findViewById<View>(R.id.logScroll) as ScrollView
logWindow = progressLayout!!.findViewById<View>(R.id.logWindow) as TextView
logWindow!!.setText(null, TextView.BufferType.EDITABLE)
progressBar!!.progress = 0
progressBar!!.max = 100

initDevicePrepScreen()
val fragmentView = inflater.inflate(R.layout.activity_fragment, container, false)

li = LayoutInflater.from(activity)
deviceContainer = fragmentView.findViewById(R.id.deviceLayoutContainer) as ViewFlipper
devicePrep = inflater.inflate(R.layout.device_prep, deviceContainer, true)
progressLayout = inflater.inflate(R.layout.progress, deviceContainer, true)

return fragmentView
>     }

这是我从活动中调用它的地方:

bluetoothGattReceiver =
            object : BluetoothGattReceiver() {
                override fun onReceive(context: Context, intent: Intent) {
                    super.onReceive(context, intent)

                    if (updatesFragment == null) {
                        updatesFragment = UpdatesFragment()
                    }
                    updatesFragment!!.processStep(intent)

如何在运行之前调用onCreateView()?updatesFragment!!.processStep(intent)

下面是堆栈跟踪:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.unobatteries.unobmsapp, PID: 31486
    java.lang.NullPointerException
        at com.unobatteries.unobmsapp.fragments.UpdatesFragment.processStep(UpdatesFragment.kt:85)
        at com.unobatteries.unobmsapp.activities.UpdatesActivity$onResume$2.onReceive(UpdatesActivity.kt:144)
        at androidx.localbroadcastmanager.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:313)
        at androidx.localbroadcastmanager.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:121)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8653)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
fun processStep(intent: Intent?) {
        bluetoothManager2!!.processStep(intent) // Line 85
    }
android kotlin android-fragments nullpointerexception fragment-oncreateview

评论

0赞 Code-Apprentice 4/6/2022
请给出一个再现错误的最小可重现示例。确切的错误是什么?哪一行导致了错误?您使用 创建了一个 fragment 对象,但您是否曾经将此 fragment 设置为要显示的 Activity 的当前 fragment?updatesFragment = UpdatesFragment()
0赞 Dylon Jaynes 4/6/2022
@Code-Apprentice 我认为是我在活动中调用 processStep(intent) 的行导致了问题。我编辑了我的问题并包含堆栈跟踪。在调用 onCreateView() 之前,我是否需要让活动显示它?
0赞 Code-Apprentice 4/6/2022
该错误会确切地告诉您问题出在哪一行:“at com.unobatteries.unobmsapp.fragments.UpdatesFragment.processStep(UpdatesFragment.kt:89)UpdatesFragments.kt”。所以没有必要猜测。. At the end here, it says the error occurs on line 89 of
1赞 Code-Apprentice 4/6/2022
那看起来不对。 不能导致 .堆栈跟踪显示异常发生在 内部,而不是 。自运行代码并获取此堆栈跟踪以来,您是否编辑了代码?这样做会导致堆栈跟踪中的行号与当前版本代码中的行号不匹配。this.disconnected = disconnectedNullPointerExceptionprocessStep()setDisconnected()
1赞 Dylon Jaynes 4/6/2022
@Code-Apprentice 哦,哇,我刚刚再次运行它,现在是第 85 行抛出错误,这是我的片段中的 processStep() 函数,所以这更有意义。谢谢你指出这一点!

答:

1赞 Dylon Jaynes 4/6/2022 #1

更新:我意识到我需要在不显示片段的情况下调用此函数,同时仍然访问它引用的 bluetoothManager 类。有人向我指出,我不需要我的片段实例来访问 bluetoothManager 中的函数,因为片段主要用于处理 ui 组件。

由于 BluetoothManager 类是抽象的,因此在我的活动中,我声明了一个 SuotaManager 类的实例,该实例扩展了 BluetoothManager 并在该实例上调用了 processStep(),从而解决了问题!

评论

0赞 Code-Apprentice 4/6/2022
虽然这解决了您立即遇到的问题,但以这种方式做事存在问题。片段旨在保存要显示的 UI 组件,但您创建的片段实例只是为了访问其中的组件。这表明该类要么属于活动,要么属于该活动可以使用的另一个非 UI 类,而不是属于片段。bluetoothManagerbluetoothManager
0赞 Code-Apprentice 4/6/2022
另请注意,如果 是 ,则不会调用的手段是 。这避免了您最初询问的 NPE,但可能不会创建您想要的行为。?.processStep()bluetoothManagernull
1赞 Dylon Jaynes 4/6/2022
@Code学徒:好吧,我明白你的意思了。我刚刚意识到该活动已经包含对 bluetoothManager 的引用,但不是它的实例,因为它是一个抽象类。因此,在我的活动中,我声明了一个 SuotaManager 类的实例,该类扩展了 BluetoothManager 类并在其上调用了 processStep()(一个抽象函数)。现在它按预期工作!我将更新我的答案以包含此解决方案。非常感谢你对我的帮助!
0赞 Code-Apprentice 4/7/2022
很高兴听到你正在弄清楚。请注意,“已经保留了对 bluetoothManager 的引用,但不是实例”没有多大意义,因为“引用”必须引用“实例”。我认为这只是当你试图传达你在代码中看到的内容时对术语的误用。随着您的不断学习,您对正确使用术语的理解和能力将得到提高。
1赞 Dylon Jaynes 4/7/2022
谢谢!我很欣赏更正。我还错误地假设此代码引用了我的自定义类,而实际上它引用了库中的BluetoothManager,因此即使该类不是抽象的,也不会引用它。哈哈!private lateinit var bluetoothManager: BluetoothManagercom.unobatteries.unobmsapp.ota.BluetoothManagerandroid.bluetooth