java.lang.IllegalStateException: pb не должен быть нулевым в TopHeadlinesFragment?

Я разрабатываю новостное приложение, и я внедрил живые данные с индикатором выполнения, но я получаю следующее исключение в своем коде

java.lang.IllegalStateException: pb must not be null
 at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment$initViewModel$2.onChanged(TopHeadlinesFragment.kt:60)
 at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment$initViewModel$2.onChanged(TopHeadlinesFragment.kt:22)
 at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
 at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:144)
 at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:442)
 at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:394)
 at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361)
 at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300)
 at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339)
 at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145)
 at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131)
 at androidx.fragment.app.Fragment.performStart(Fragment.java:2637)
 at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:915)
 at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
 at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
 at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
 at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
 at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
 at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
 at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
 at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
 at android.os.Handler.handleCallback(Handler.java:873)
 at android.os.Handler.dispatchMessage(Handler.java:99)
 at android.os.Looper.loop(Looper.java:201)
 at android.app.ActivityThread.main(ActivityThread.java:6820)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:922)

ниже моего класса TopHeadlinesFragment.kt

class TopHeadlinesFragment : Fragment() {

    private  var binding: FragmentTopHeadlinesBinding? = null
    private val viewModel by viewModel<MainViewModel>()
    private lateinit var topHeadlinesAdapter: TopHeadlinesAdapter
    // private   val newsRepository: NewsRepository by inject()
    private  var article:List<Article>? = null


    //3
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(
            R.layout.fragment_top_headlines
            , container, false
        )
        val recyclerView = view.findViewById(R.id.recyclerView) as RecyclerView
        val pb = view.findViewById(R.id.pb) as ProgressBar
        topHeadlinesAdapter = TopHeadlinesAdapter(recyclerView.context, article)
        recyclerView.layoutManager = LinearLayoutManager(context)
        recyclerView.adapter = topHeadlinesAdapter
        initViewModel()

        binding?.lifecycleOwner
        return binding?.root


    }

    private fun initViewModel() {
        viewModel?.sportList?.observe(this, Observer { newList ->
            topHeadlinesAdapter.updateData(newList)
        })

        viewModel?.showLoading?.observe(this, Observer { showLoading ->
            pb.visibility = if (showLoading) View.VISIBLE else View.GONE
        })

        viewModel?.showError?.observe(this, Observer { showError ->
            (showError)
        })

        viewModel?.loadNews()
    }
}

ниже фрагмент_top_headlines.xml

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ProgressBar
        android:id="@+id/pb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

I have followed all stackoverflow suggestion it did not solve my problem. what I want to know where exactly I am making mistake what I have to in order avoid an exception.

что я пробовал

1. Недействительный перезапуск кеша 2. Очистить и перестроить проект 3. Я проверил, что индикатор выполнения уже инициализирован. 4. Я также попробовал эту ссылку stackoverflow используя Kotlin 5. Я пробовал индикатор выполнения, объявленный как глобальная переменная, но это не сработало

ниже моего MainViewModel.kt

@Suppress("UNCHECKED_CAST")
class MainViewModel(val newsRepository: NewsRepository) : ViewModel(), CoroutineScope {
    // Coroutine's background job
    val job = Job()
    // Define default thread for Coroutine as Main and add job
    override val coroutineContext: CoroutineContext = Dispatchers.Main + job

    val showLoading = MutableLiveData<Boolean>()
    val sportList = MutableLiveData<List<Article>>()
    val showError = SingleLiveEvent<String>()

    fun loadNews() {
        // Show progressBar during the operation on the MAIN (default) thread
        showLoading.value = true
        // launch the Coroutine
        launch {
            // Switching from MAIN to IO thread for API operation
            // Update our data list with the new one from API
            val result = withContext(Dispatchers.IO) {
                newsRepository?.getNewsList()
            }
            // Hide progressBar once the operation is done on the MAIN (default) thread
            showLoading.value = false
            when (result) {

                is UseCaseResult.Success<*> -> {
                    sportList.value = result.data as List<Article>
                }
                is Error -> showError.value = result.message
            }
        }
    }

    override fun onCleared() {
        super.onCleared()
        // Clear our job when the linked activity is destroyed to avoid memory leaks
        job.cancel()
    }
}

Я также пробовал ниже предоставленные ответы, но это не решило проблему


person sashabeliy    schedule 18.03.2020    source источник
comment
Не уверен, но просто подумал, что val pb не является глобальным и доступен только в методе onCreateView, попробуйте сделать его глобальным и проверьте, работает ли он.   -  person Manoj Mohanty    schedule 18.03.2020
comment
каково ваше предложение, оно все еще появляется, я объявил его глобальным, но это все еще сбой приложения, дающий указанное выше исключение   -  person sashabeliy    schedule 18.03.2020
comment
да, я хочу знать, где я делаю ошибку   -  person sashabeliy    schedule 18.03.2020
comment
Вы используете привязку данных? другим способом было бы просто прокомментировать код, который выдает ошибку, и проверить, обновлен ли ваш recyclerview после загрузки данных.   -  person Manoj Mohanty    schedule 18.03.2020
comment
следующим было бы поставить отладчик в точное место и проверить, почему он нулевой   -  person Manoj Mohanty    schedule 18.03.2020
comment
да, я использую привязку данных, но я все еще новичок в привязке данных, поэтому ваше предложение можно объяснить с помощью примера кодирования   -  person sashabeliy    schedule 18.03.2020
comment
Давайте продолжим обсуждение в чате.   -  person sashabeliy    schedule 18.03.2020


Ответы (2)


вы не инициализировали свою привязку:

 private  var binding: FragmentTopHeadlinesBinding? = null

это все равно ноль

person Nurseyit Tursunkulov    schedule 18.03.2020
comment
я думаю дело не в этом - person sashabeliy; 18.03.2020
comment
это этот случай, иначе где вы его инициализируете? - person Nurseyit Tursunkulov; 19.03.2020

    viewModel?.sportList?.observe(this, Observer { newList ->
        topHeadlinesAdapter.updateData(newList)
    })

    viewModel?.showLoading?.observe(this, Observer { showLoading ->
        pb.visibility = if (showLoading) View.VISIBLE else View.GONE
    })

    viewModel?.showError?.observe(this, Observer { showError ->
        (showError)
    })

Должно быть

    viewModel.sportList.observe(viewLifecycleOwner) { newList ->
        topHeadlinesAdapter.updateData(newList)
    }

    viewModel.showLoading.observe(viewLifecycleOwner) { showLoading ->
        pb.visibility = if (showLoading) View.VISIBLE else View.GONE
    }

    viewModel.showError.observe(viewLifecycleOwner) { showError ->
        (showError)
    }

Возможно, вы захотите превратить viewModel в lateinit var.

person EpicPandaForce    schedule 18.03.2020
comment
Ну тогда исправьте ошибки. Например, добавьте lifecycle-ktx и импортируйте функцию расширения, которая позволит вам не вводить Observer { все время. - person EpicPandaForce; 18.03.2020
comment
спасибо за ваш ответ, но ваш код не работает, лучше используйте мой старый код - person sashabeliy; 18.03.2020
comment
Вы должны использовать viewLifecycleOwner, но вы делаете это ¯\_(ツ)_/¯ - person EpicPandaForce; 18.03.2020
comment
Вы можете увидеть мой MainViewModel.kt? Я хочу знать, где именно я делаю ошибку в Fragment, а My FragmentTopHeadlinesBinding неправильно реализуется, верно? - person sashabeliy; 18.03.2020
comment
как вы думаете, что главная проблема - person sashabeliy; 18.03.2020