Closed DatL4g closed 2 years ago
You try to access in another thread (from Coroutine). I think View can be destroyed and that's why ViewBinding can't be created
Mhm no I don't think so. Or did I miss something? I navigate back there in the Main thread
I start the flow collection in onViewCreated and do it the official recommended way (This should collect the flow in main thread)
inline fun <T> Flow<T>.launchAndCollectIn(
owner: LifecycleOwner,
minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
crossinline action: suspend CoroutineScope.(T) -> Unit
) = owner.lifecycleScope.launch {
owner.repeatOnLifecycle(minActiveState) {
collect {
action(it)
}
}
}
navArgs.seriesWithInfo?.let { series ->
setViewData(series)
burningSeriesViewModel.getSeriesData(series.series.href, series.series.hrefTitle).launchAndCollect {
seriesFlowCollect(it)
}
}
And the navigation from HomeFragment works (but uses another navArg)
I am working on release with better error description that will help easier understand the reason
Nice. I look forward to it
Version 1.5.4 must be available in few hours
I cannot resolve Version 1.5.4 although the README displays version 1.5.4 (badge) and https://mvnrepository.com/artifact/com.github.kirich1409/viewbindingpropertydelegate/1.5.4 exists. Can you check that?
I already tried Invalidate and Restart in Android Studio as well as Refresh Dependencies using the Gradle tab in Android Studio.
Gradle Sync output:
Failed to resolve: viewbindingpropertydelegate-1.5.4
Affected Modules: app
Gradle implementation:
implementation("com.github.kirich1409:viewbindingpropertydelegate:1.5.4")
I've checked and has no any issues. Try to remove Gradle cache in $HOME/.gradle/caches and try again to build your project
Just deleted the folder, opened the project and downloaded everything. Still said it cannot resolve the dependency (1.5.3 however can), tried to build anyway
FAILURE: Build completed with 8 failures.
1: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':app:dataBindingMergeDependencyArtifactsDebug'.
> Could not resolve all files for configuration ':app:debugCompileClasspath'.
> Failed to transform viewbindingpropertydelegate-1.5.4.aar (com.github.kirich1409:viewbindingpropertydelegate:1.5.4) to match attributes {artifactType=android-databinding, org.gradle.category=library, org.gradle.dependency.bundling=external, org.gradle.libraryelements=aar, org.gradle.status=release, org.gradle.usage=java-api}.
> Could not find viewbindingpropertydelegate-1.5.4.aar (com.github.kirich1409:viewbindingpropertydelegate:1.5.4).
Searched in the following locations:
https://repo.maven.apache.org/maven2/com/github/kirich1409/viewbindingpropertydelegate/1.5.4/viewbindingpropertydelegate-1.5.4.aar
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
==============================================================================
Other 7 errors are the same but other task names
There is no aar file, only jars and checksums etc https://repo.maven.apache.org/maven2/com/github/kirich1409/viewbindingpropertydelegate/1.5.4/
I've published 1.5.5 few minutes ago
Resolving 1.5.5 works however the is a duplicate class issue which prevents the app from building. (Building still works fine when I switch back to 1.5.3, already checked my dependency tree)
Execution failed for task ':app:checkDebugDuplicateClasses'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
> Duplicate class by.kirich1409.viewbindingdelegate.ViewBindingPropertyDelegateKt found in modules jetified-viewbindingpropertydelegate-1.5.5-runtime (com.github.kirich1409:viewbindingpropertydelegate:1.5.5) and jetified-viewbindingpropertydelegate-noreflection-1.5.5-runtime (com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.5)
Duplicate class by.kirich1409.viewbindingdelegate.ViewBindingPropertyDelegateKt$viewBindingWithLifecycle$1 found in modules jetified-viewbindingpropertydelegate-1.5.5-runtime (com.github.kirich1409:viewbindingpropertydelegate:1.5.5) and jetified-viewbindingpropertydelegate-noreflection-1.5.5-runtime (com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.5)
Duplicate class by.kirich1409.viewbindingdelegate.ViewBindingPropertyDelegateKt$viewBindingWithLifecycle$2 found in modules jetified-viewbindingpropertydelegate-1.5.5-runtime (com.github.kirich1409:viewbindingpropertydelegate:1.5.5) and jetified-viewbindingpropertydelegate-noreflection-1.5.5-runtime (com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.5)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
Switched to the noreflection
variant for now.
This builds fine
Back to the original issue:
The log shows
2022-01-05 22:25:46.868 16285-4024/de.datlag.burningseries E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-3
Process: de.datlag.burningseries, PID: 16285
java.lang.IllegalStateException: Fragment's view can't be accessed. Fragment isn't added
at by.kirich1409.viewbindingdelegate.LifecycleViewBindingProperty.getValue(ViewBindingProperty.kt:87)
at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.getValue(FragmentViewBindings.kt:63)
at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.getValue(FragmentViewBindings.kt:52)
at de.datlag.burningseries.ui.fragment.ScrapeHosterFragment.getBinding(ScrapeHosterFragment.kt:34)
at de.datlag.burningseries.ui.fragment.ScrapeHosterFragment.access$getBinding(ScrapeHosterFragment.kt:29)
at de.datlag.burningseries.ui.fragment.ScrapeHosterFragment$saveStream$1$1.invokeSuspend(ScrapeHosterFragment.kt:92)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:233)
at android.app.ActivityThread.main(ActivityThread.java:8030)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)
It says that it cannot access the ScrapeHosterFragment well because thats true, the fragment I navigated to is SeriesFragment not ScrapeHosterFragment
That's the snippet where I navigate back and triggers this issue
binding.backButton.setOnClickListener {
findNavController().navigate(SaveScrapedDialogDirections.actionSaveScrapedDialogToSeriesFragment(seriesWithInfo = navArgs.seriesWithInfo))
}
View isn't ready and how you want to create instance of ViewBinding?
If you want to look at any fragment it's here https://github.com/DATL4G/BurningSeries-Android/tree/master/app/src/main/java/de/datlag/burningseries/ui/fragment
Basically I do everything the same in fragments:
I navigate from SeriesFragment to ScrapeHosterFragment
class SeriesFragment : AdvancedFragment(R.layout.fragment_series) {
private val binding: FragmentSeriesBinding by viewBinding()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Access the views here using binding.view.setOnClickListener { /* for example */ }
}
}
I navigate from ScrapeHosterFragment to SaveScrapedDialog
class ScrapeHosterFragment : AdvancedFragment(R.layout.fragment_scrape_hoster) {
private val binding: FragmentScrapeHosterBinding by viewBinding()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Access the views here
}
}
Navigation explained in comment
class SaveScrapedDialog : BottomSheetDialogFragment() {
private val binding: DialogSaveScrapedBinding by viewBinding()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
if (safeContext.packageManager.isTelevision()) {
dialog?.setOnShowListener {
it.expand()
}
}
return inflater.inflate(R.layout.dialog_save_scraped, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.continueButton.setOnClickListener {
dismiss()
}
// I navigate here from SaveScrapedDialog to SeriesFragment and it causes the issue on the ScrapeHosterFragment
binding.backButton.setOnClickListener {
findNavController().navigate(SaveScrapedDialogDirections.actionSaveScrapedDialogToSeriesFragment(seriesWithInfo = navArgs.seriesWithInfo))
}
}
}
You execute Coroutine in saveStream()
on background thread, and it has no guarantee to be executed when Fragment is attached or not destroyed. Before call UI check that
private fun saveStream() = lifecycleScope.launch(Dispatchers.IO) {
val scrapeJsInput = safeContext.resources.openRawResource(R.raw.scrape_hoster)
val jsText = String(scrapeJsInput.readBytes())
while (true) {
if (getView() != null) {
withContext(Dispatchers.Main) {
binding.webView.evaluateJavascript(jsText) {
if (it != null && it.isNotEmpty() && !it.equals("null", true)) {
saveScrapedData(it)
}
}
}
delay(3000)
} else {
// Do something when view has been destroyed
}
}
}
Or you can run coroutine attached to viewLifecycle. Read more about that here.
I'm facing an issue with the latest version (1.5.3) where
Host view isn't ready to create a ViewBinding instance
occurs.Full Stacktrace:
I'm able to reproduce this consistently BurningSeries-Android inside the SeriesFragment. The normal way I navigate there is from HomeFragment and this works fine, however when I navigate to the VideoFragment from there and then to the ScrapeHosterFragment and after that to the SaveScrapedDialog lastly back to the SeriesFragment the app crashes because of this error.
It's maybe hard to understand but basicly the navigation hierarchy looks like this:
HomeFragment -> SeriesFragment = FINE
HomeFragment -> SeriesFragment -> VideoFragment -> StreamUnavailableDialog -> ScrapeHosterFragment -> SaveScrapedDialog -> SeriesFragment = ERROR
All navigations are done using the NavigationComponent with SafeArgs. I'm accessing the views in the onViewCreated method.