Android: LiveData observeForEver produce crash because the views are null - android

For the purposes of my application I have live data that observesForEver and updates views. When I exit the application to background and return to foreground the application crashes in the views that is in the observers.
Here is the crash:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.emoona.music, PID: 7897
java.lang.NullPointerException: this.titleTxt must not be null
at com.emoona.torahboxmusic.features.playmusic.playlist.SelectPlaylistFragment.updateUI(SelectPlaylistFragment.kt:157)
................
My code:
viewModel.globalController.music.observeForever { music ->
val music = music ?: return#observeForever
this.titleTxt.text = music.title
}
I declare the observer on onViewCreated
What should I do to avoid this crash? Why are views null in the observer?
I specify I don't want to do an observe(viewLifeCycle) because I need it to observeForEver

Related

Flutter AndroidView throws Unhandled Exception: PlatformException

Created native UI for Video calling using opentok library in. Flutter.
The UI is rendering successfully for the first time, But gives below exception when user. press the back button and again rejoins the call.
Unhandled Exception: PlatformException(error, java.lang.IllegalStateException: The Android view returned from PlatformView#getView() was already added to a parent view.
This is the code that we are using to create native View.
return AndroidView(
viewType: 'opentok-video-container',
creationParams: args,
creationParamsCodec: PlatFormSpecificView._decoder);```
How can we destroy or recreate AndroidView onBackpressed event of flutter?

UI Change in Back Ground Thread

i have a function and this function send http request in back Ground Thread
when request is excute and complete i have some line of code to make UI Change but when fragment pause the app crash Because the function cant make UI Change when fragment pause i dont now what i must do for solve this
val url = "BASE_DIR/example"
val client = OkHttpClient()
val request = Request.Builder().url(url).build()
val code = client.newCall(request).execute().code()
if (code == 200) {
fragment.requireActivity().runOnUiThread {
fragment.refresh.isRefreshing = false
}
Another way to send a message to the UI thread is with a Handler
Handler(Looper.getMainLooper()).post {
// do whatever
}
or you have the usual postDelayed methods etc. So you can update fragment without it needing to be attached to an Activity, which is probably better than just doing a null check on getActivity (the fragment might just be temporarily detached, so you still want to update its state so you don't "lose" the result).
If you don't mind losing the result, because you're treating the detached fragment as dead so it doesn't need to be updated, then the null check like in #rahat's answer is the simplest way to do it. Don't make it more complicated than it needs to be!
Try with
fragment.getActivity()?.runOnUiThread {
fragment.refresh?.isRefreshing = false
}
The issue is when the fragment is detached the requireActivity()
will throw IllegalStateException so since it is not associated with any activity, but getActivity() returns null if it is not associated with any activity, so with null safe call you can do it safely.

Log Stacktrace to FirebaseDatabase in UncaughtExceptionHandler, problem calling default uncaughtException method

I'm currently stuck with UncaughtExceptionHandler and Firebase Database in my Android Kotlin App.
My plan:
In the case of an uncaught exception, log the stack trace to Google Firebase.
I already have an BaseCompatActivity with an UncaughtExceptionHandler. All activities inherit from this class.
The only and the interesting part from BaseCompatActivity follows:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val currentUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler()
Thread.setDefaultUncaughtExceptionHandler({ thread, exception ->
val exStackTraceString = StringWriter()
exception.printStackTrace(PrintWriter(exStackTraceString))
FirebaseDatabase.getInstance().getReference("/exception-log").push().setValue(exStackTraceString.toString()).addOnCompleteListener {
currentUncaughtExceptionHandler.uncaughtException(thread, exception)
}
})
}
Everything is working except the the default method call for currentUncaughtExceptionHandler.uncaughtException(thread, exception) because this line is never called. It seems that the complete listener never gets called. This leads to an non-closed, unusable App after the exception occured :-(
The logging into the Firebase Database is working. The only broken thing is the listener callback method.
I don't want to use System.exit() because this breaks the Exception Chain.
Can you help me?
From the documentation of Thread.setDefaultUncaughtExceptionHandler:
"Set the default handler invoked when a thread abruptly terminates due to an uncaught exception"
Your call to your Firebase Database uses an asynchronous callback. Without more information, it's hard to be sure, but considering your UI is getting stuck, something off of your Main thread is getting killed. You're able to make the call, but the result doesn't have a thread to return to because the thread has been terminated.
If you're using Firebase, I'd suggest looking at Crashlytics, they have a method for handling this.

How to handle addListenerForSingleValue properly after onSaveInstanceState

I'm using Firebase from a long time and I really appreciate its flexibility to fetch some data from its realtime database with low effort. However, I'm having some problems on handling the result of the call of addListenerForSingleValueEvent.
Every time some UI operation has to be performed after it returns my application crashes if onSaveInstanceState has already been called.
There is any way to abort the operation during onPause() the same way we can do with addValueEventListener?
I know that a solution could be checking if onSaveInstanceState has already been called but all solution I tried seems to be unreliable.
I try checking for methods like:
isAdded()
isVisible()
isFinishing()
both for fragments and activities.
An example of my attemps is:
dbref.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
if(isAdded && isVisible && activity?.isFinishing == false){
GenericMessageDialog.newInstance(getString(R.string.generic_error_title), errorMessage).show(activity?.supportFragmentManager, "ed")
}
}
Sometimes this exception is thrown
Fatal Exception: java.lang.IllegalStateException
Can not perform this action after onSaveInstanceState

Checking State before calling activity.getSupportFragmentManager().popBackStackImmediate()?

Sometimes calling
activity.getSupportFragmentManager().popBackStackImmediate()
results in an error in particular:
Fatal Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
What check will prevent this error from occurring? is it enough to check
!activity.isFinishing()
Or should one check also that activity is not stopped?

Categories

Resources