Home > OS >  An exception happened in constructor of class com.mgr.ui.viewmodels.MainViewModel
An exception happened in constructor of class com.mgr.ui.viewmodels.MainViewModel

Time:08-01

I am working on an application. I am trying to restore the state, when I return to the application from putting it into the background. I got an exception for which I currently have no idea why it happened. So, I decided to post here, to hopefully have someone spot what I am unable to see currently.

Exception:

java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.mgr/com.mgr.MainActivity}: 
java.lang.RuntimeException: An exception happened in constructor of class com.mgr.ui.viewmodels.MainViewModel

This can be traced back to: androidx.lifecycle.ViewModelProvider.Factory

internal fun <T : ViewModel?> newInstance(
    modelClass: Class<T>,
    constructor: Constructor<T>,
    vararg params: Any
): T {
    return try {
        constructor.newInstance(*params)
    } catch (e: IllegalAccessException) {
        throw RuntimeException("Failed to access $modelClass", e)
    } catch (e: InstantiationException) {
        throw RuntimeException("A $modelClass cannot be instantiated.", e)
    } catch (e: InvocationTargetException) {
        throw RuntimeException(
            "An exception happened in constructor of $modelClass", e.cause
        )
    }
}

More of my own code now:

MainViewModel.tk

@HiltViewModel
class MainViewModel @Inject constructor(
    private val savedStateHandle: SavedStateHandle,
) : ViewModel()
{
    companion object {
        const val UI_MENU_STATE = "ui.menu.state"
    }

    init {
        savedStateHandle.get<Boolean>(UI_MENU_STATE)?.let {
                m -> onMenuStateChange(m);
        }
    }

    private var m_title by mutableStateOf("")
    private var displayMenu by mutableStateOf( false)

    var tosVisible by mutableStateOf( false)
        internal set

    fun updateTitleState(title: String){
        m_title = title;
    }

    fun onMenuStateChange(open: Boolean){
        Log.d("App", open.toString());
        displayMenu = open;
        savedStateHandle.set<Boolean>(UI_MENU_STATE, displayMenu);
    }

    fun isMenuOpen(): Boolean {
        return displayMenu;
    }

    fun getTitle(): String { return m_title; }
}

MainActivity:

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val mainViewModel = ViewModelProvider(
            this,
            SavedStateViewModelFactory(application, this)
        )[MainViewModel::class.java]

        setContent {
            MgrTheme {
                Surface(color = MaterialTheme.colorScheme.background) { Main(mainViewModel) }
            }
        }
    }
}

FULL STACK TRACE:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.mgr, PID: 11242
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mgr/com.mgr.MainActivity}: java.lang.RuntimeException: An exception happened in constructor of class com.mgr.ui.viewmodels.MainViewModel
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3676)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3813)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2308)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7898)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
     Caused by: java.lang.RuntimeException: An exception happened in constructor of class com.mgr.ui.viewmodels.MainViewModel
        at androidx.lifecycle.SavedStateViewModelFactoryKt.newInstance(SavedStateViewModelFactory.kt:234)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.kt:133)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:187)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:153)
        at com.mgr.MainActivity.onCreate(MainActivity.kt:43)
        at android.app.Activity.performCreate(Activity.java:8290)
        at android.app.Activity.performCreate(Activity.java:8269)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3657)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3813) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2308) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loopOnce(Looper.java:201) 
        at android.os.Looper.loop(Looper.java:288) 
        at android.app.ActivityThread.main(ActivityThread.java:7898) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) 
     Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void androidx.compose.runtime.MutableState.setValue(java.lang.Object)' on a null object reference
        at com.mgr.ui.viewmodels.MainViewModel.setDisplayMenu(MainViewModel.kt:54)
        at com.mgr.ui.viewmodels.MainViewModel.onMenuStateChange(MainViewModel.kt:40)
        at com.mgr.ui.viewmodels.MainViewModel.<init>(MainViewModel.kt:24)
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
        at androidx.lifecycle.SavedStateViewModelFactoryKt.newInstance(SavedStateViewModelFactory.kt:228)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.kt:133) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:187) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:153) 
        at com.mgr.MainActivity.onCreate(MainActivity.kt:43) 
        at android.app.Activity.performCreate(Activity.java:8290) 
        at android.app.Activity.performCreate(Activity.java:8269) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3657) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3813) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2308) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loopOnce(Looper.java:201) 
        at android.os.Looper.loop(Looper.java:288) 
        at android.app.ActivityThread.main(ActivityThread.java:7898) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) 

EDIT: Passing into a separate @Composable method.

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Main(viewModel: MainViewModel = androidx.lifecycle.viewmodel.compose.viewModel()) {

CodePudding user response:

Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void androidx.compose.runtime.MutableState.setValue(java.lang.Object)' on a null object reference

You can try moving your init {} block to be after you declare displayMenu. I am not confident that this will work, but it is worth a try.

If that does not help, then you may need to postpone your use of the SavedStateHandle until sometime when the MutableState is ready for use.

  • Related