android - 安卓 - 使用dagger將ViewModelProvider.Factory注入到不同的Activity

我有以下Activity,當請求成功,API返回有效的LoggedInUser時,我想導航到不同的Activity,並且仍然可以訪問LoggedInUser。

以下是loginActivity:


class LoginActivity : AppCompatActivity() {



 val vmFactory = MainViewModelFactory()


 lateinit var viewModel: MainViewModel



 override fun onCreate(savedInstanceState: Bundle?) {


 super.onCreate(savedInstanceState)


 setContentView(R.layout.activity_login)


 val button: Button = findViewById(R.id.button)


 button.setOnClickListener { onButtonClick() }


 val label: TextView = findViewById(R.id.counter)



 viewModel = ViewModelProvider(this, vmFactory).get(MainViewModel::class.java)


 println("stack: ${viewModel.hashCode()}")



 viewModel.userLogin.observe(this, Observer{ user ->


 print("Debug: ${user}")


 if(user != null){


 label.text = user.user.name


 redirectToNextActivity()



 }



 })



 }



 fun onButtonClick(){


 var username: EditText = findViewById(R.id.username)


 var password: EditText = findViewById(R.id.password)


 println(username.text.toString())


 println(password.text.toString())


 viewModel.setUser(username.text.toString(), password.text.toString())


 }



 fun redirectToNextActivity(){


 println("Login done!")


 val intent = Intent(this, SampleActivity::class.java)


 startActivity(intent)


 }



}



以下是ViewModel和ViewModelFactory:

MainViewModel:


class MainViewModel : ViewModel(){



 var _request = MutableLiveData<LoginRequest>()



 val userLogin: LiveData<LoggedInUser> = Transformations


 .switchMap(_request){req ->


 MainRepository.authenticatePlease(req.username, req.password)


 }



 fun setUser(username: String, password: String){


 val update = LoginRequest(username, password)


 if(_request.value == update){


 return


 }


 _request.value = update


 }



}



這是工廠:


class MainViewModelFactory: ViewModelProvider.Factory {


 override fun <T : ViewModel?> create(modelClass: Class<T>): T {


 return MainViewModel() as T


 }


}



當我嘗試在新的Activity中獲取工廠時,我得到以下錯誤:

SampleActivity has no zero argument constructor

然後,我嘗試在vmFactory中傳遞loginActivity,如下所示:

val intent = Intent(this, SampleActivity(vmFactory)::class.java)

我還是得到同樣的錯誤。

SampleActivity如下所示:


class SampleActivity@Inject constructor(private val factory: ViewModelProvider.Factory) : AppCompatActivity() {



 lateinit var viewModel: MainViewModel



 override fun onCreate(savedInstanceState: Bundle?) {


 super.onCreate(savedInstanceState)


 setContentView(R.layout.activity_sample)


 viewModel = ViewModelProvider(this, factory).get(MainViewModel::class.java)



 }


}



有什麼幫助!

时间: 作者:

  • 不應將參數添加到Activity的構造函數

由於Android操作系統控制Activity,BroadcastReceiver,Service,ContentProvider和Application類的實例化,因此開發人員無權訪問Android組件的構造函數。

請查看更多信息:https://levelup.gitconnected.com/understanding-dependency-injection-in-android-af1bb2b7984e

  • 如果希望訪問示例LoggedInUser中的Activity,可以在Intent中將對象作為附加參數發送

    
    fun redirectToNextActivity(loggedInUser: LoggedInUser) {
    
    
    println("Login done!")
    
    
    val intent = Intent(this, SampleActivity::class.java)
    
    
    intent.putExtra("extra", loggedInUser)
    
    
    startActivity(intent)
    
    
    }
    
    
    
    

    或者,可以將MainViewModel類標記為Singleton,以便接收兩個activity中的相同實例

作者:
...