java.lang.RuntimeException: Failed to call observer method

2.1k Views Asked by At

Please help me with my problem. The app with these same codes was working perfectly but now the app crashes whenever I try to navigate from Overview fragment to Detail fragment.

I have not changed any line of code still the app is crashing. Please help me with this.

Here is the logcat:

    Process: com.example.marsrealestate, PID: 4158
    java.lang.RuntimeException: Failed to call observer method
        at androidx.lifecycle.ClassesInfoCache$MethodReference.invokeCallback(ClassesInfoCache.java:226)
        at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeMethodsForEvent(ClassesInfoCache.java:194)
        at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeCallbacks(ClassesInfoCache.java:185)
        at androidx.lifecycle.ReflectiveGenericLifecycleObserver.onStateChanged(ReflectiveGenericLifecycleObserver.java:37)
        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:2735)
        at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:365)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1194)
        at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1997)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        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:6806)
        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:873)
     Caused by: java.util.IllegalFormatPrecisionException: 79
        at java.util.Formatter$FormatSpecifierParser.<init>(Formatter.java:2613)
        at java.util.Formatter.parse(Formatter.java:2557)
        at java.util.Formatter.format(Formatter.java:2504)
        at java.util.Formatter.format(Formatter.java:2458)
        at java.lang.String.format(String.java:2883)
        at android.content.res.Resources.getString(Resources.java:478)
        at android.content.Context.getString(Context.java:603)
        at com.example.marsrealestate.detail.DetailViewModel$displayPropertyPrice$1.apply(DetailViewModel.kt:26)
        at com.example.marsrealestate.detail.DetailViewModel$displayPropertyPrice$1.apply(DetailViewModel.kt:11)
        at androidx.lifecycle.Transformations$1.onChanged(Transformations.java:76)
        at androidx.lifecycle.MediatorLiveData$Source.onChanged(MediatorLiveData.java:152)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:144)
        at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:443)
        at androidx.lifecycle.LiveData.observeForever(LiveData.java:232)
        at androidx.lifecycle.MediatorLiveData$Source.plug(MediatorLiveData.java:141)
        at androidx.lifecycle.MediatorLiveData.onActive(MediatorLiveData.java:118)
        at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:437)
        at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:395)
        at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361)
        at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:188)
        at androidx.lifecycle.LiveData.observe(LiveData.java:203)
        at androidx.databinding.ViewDataBinding$LiveDataListener.addListener(ViewDataBinding.java:1626)
        at androidx.databinding.ViewDataBinding$LiveDataListener.addListener(ViewDataBinding.java:1574)
        at androidx.databinding.WeakListener.setTarget(WeakListener.java:85)
2022-02-05 15:43:34.998 4158-4158/com.example.marsrealestate E/AndroidRuntime:     at androidx.databinding.ViewDataBinding.registerTo(ViewDataBinding.java:729)
        at androidx.databinding.ViewDataBinding.updateRegistration(ViewDataBinding.java:653)
        at androidx.databinding.ViewDataBinding.updateLiveDataRegistration(ViewDataBinding.java:691)
        at com.example.marsrealestate.databinding.FragmentDetailBindingImpl.executeBindings(FragmentDetailBindingImpl.java:183)
        at androidx.databinding.ViewDataBinding.executeBindingsInternal(ViewDataBinding.java:512)
        at androidx.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:484)
        at androidx.databinding.ViewDataBinding$OnStartListener.onStart(ViewDataBinding.java:1706)
        at java.lang.reflect.Method.invoke(Native Method)
        at androidx.lifecycle.ClassesInfoCache$MethodReference.invokeCallback(ClassesInfoCache.java:216)
            ... 23 more

This is the DetailViewModel class:

class DetailViewModel(marsProperty: MarsProperty, app: Application) : AndroidViewModel(app) {

    private val _selectedProperty = MutableLiveData<MarsProperty>()
    val selectedProperty : LiveData<MarsProperty>
    get() = _selectedProperty

    init {
        _selectedProperty.value = marsProperty
    }

    /**
     * This transformation tests whether the selected property is a rental.If the property is a rental,
     * the transformation chooses the appropriate string from the resources with a Kotlin when {} switch.
     */
    val displayPropertyPrice = Transformations.map(selectedProperty){
        app.applicationContext.getString(
            when(it.isRental){
                true -> R.string.display_price_monthly_rental
                false -> R.string.display_price
            }, it.price)
    }

    /**
     * This transformation concatenates multiple string resources,
     * based on whether the property type is a rental.
     */
    val displayPropertyType = Transformations.map(selectedProperty){
        app.applicationContext.getString(R.string.display_type,
        app.applicationContext.getString(
            when(it.isRental){
                true -> R.string.type_rent
                false -> R.string.type_sale
            }))
    }
}

Error is in this part:

app.applicationContext.getString(
            when(it.isRental){
                true -> R.string.display_price_monthly_rental
                false -> R.string.display_price
            }, it.price)

Here are the above two strings:

<string name="display_price_monthly_rental">$%,.Of/month</string>
    <string name="display_price">$%,.Of</string>

I have studied all the examples in StackOverflow, but nothing solved my problem. Please help.

1

There are 1 best solutions below

0
Loc Tran On

I have done the same codelab and I found that the price must be type of Float, so I have fix like this

        app.applicationContext.getString(
            when (it.isRental) {
                true -> R.string.display_price_monthly_rental
                false -> R.string.display_price
            }, it.price.toFloat())