java .lang.RuntimeException: невозможно создать экземпляр класса com.example.homeactivity.activities.editprofile.EditProfileViewModel - PullRequest
0 голосов
/ 23 января 2020

Когда я запускаю свое приложение, оно работает нормально, но когда я нажимаю «Изменить профиль», появляется сообщение об ошибке:

java .lang.RuntimeException: Невозможно запустить действие ComponentInfo {com.example.homeactivity / com.example.homeactivity.activities.editprofile.EditProfileActivity}: java .lang.RuntimeException: невозможно создать экземпляр класса com.example.homeactivity.activities.editprofile.EditProfileViewModel в * 1024. app.ActivityThread.performLaunchActivity (ActivityThread. java: 2665) в android .app.ActivityThread.handleLaunchActivity (ActivityThread. java: 2726) в android .app.ActivityThread.-wrap12 (ActivityThread. java ) в android .app.ActivityThread $ H.handleMessage (ActivityThread. java: 1477) в android .os.Handler.dispatchMessage (Обработчик. java: 102) в android .os.Looper. l oop (Looper. java: 154) в android .app.ActivityThread.main (ActivityThread. java: 6119) в java .lang.reflect.Method.invoke (собственный метод) в com . android .internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit. java: 886) at com. android .internal.os.ZygoteInit.main (ZygoteInit. java: 776) Причина: java .lang.RuntimeException: Невозможно создать экземпляр класса com.example. homeactivity.activities.editprofile.EditProfileViewModel в androidx.lifecycle.ViewModelProvider $ NewInstanceFactory.create (ViewModelProvider. java: 184) в androidx.lifecycle.ViewModelProvider $ AndroidViewModelFactory.146. * 24 *. ViewModelProvider.get (ViewModelProvider. java: 164) в androidx.lifecycle.ViewModelProvider.get (ViewModelProvider. java: 130) в com.example.homeactivity.activities.editprofile.EditProfileActivity.onCreate): Редактировать (Edit): 45: (Изменить) в android .app.Activity.performCreate (Activity. java: 6679) в android .app.Instrumentation.callActivityOnCreate (Instrumentation. java: 1118) в android .app.ActivityThread.performLaunchActivity (ActivityThread . java: 2618) при android .app.ActivityThread.handleLaunchActivity (ActivityThread. java: 2726) при android .app.ActivityThread.- wrap12 (ActivityThread. java) в android .app.ActivityThread $ H.handleMessage (ActivityThread. java: 1477) в android .os.Handler.dispatchMessage (Обработчик. java: 102) в android .os.Looper.l oop (Looper. java: 154) в android .app.ActivityThread.main (ActivityThread. java: 6119) в java .lang.reflect.Method. вызвать (собственный метод) в com. android .internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit. java: 886) в com. android .internal.os.ZygoteInit.main (ZygoteInit. java : 776) Причина: java .lang.InstantiationException: java .lang.Class не имеет конструктора с нулевым аргументом в java .lang.Class.newInstance (собственный метод) в androidx.lifecycle.ViewModelProvider $ NewInstanceFactory.create (ViewModelProvider. java: 182) в androidx.lifecycle.ViewModelProvider $ AndroidViewModelFactory.create (ViewModelProvider. java: 241) в androidx.lifecycle.ViewModelProvider.get (ViewModelProvider. java: 164) в at. ViewModelProvider.get (ViewModelProvider. java: 130) по адресу com.example.homeactivity.activities. editprofile.EditProfileActivity.onCreate (EditProfileActivity.kt: 45) в android .app.Activity.performCreate (Activity. java: 6679) в android .app.Instrumentation.callActivityOnCreate (Инструментарий. java: 1118) в android .app.ActivityThread.performLaunchActivity (ActivityThread. java: 2618) в android .app.ActivityThread.handleLaunchActivity (ActivityThread. java: 2726) в android .app.ActivityThread.-wrap12 ( ActivityThread. java) в android .app.ActivityThread $ H.handleMessage (ActivityThread. java: 1477) в android .os.Handler.dispatchMessage (Обработчик. java: 102) в android .os.Looper.l oop (Looper. java: 154) в android .app.ActivityThread.main (ActivityThread. java: 6119) в java .lang.reflect.Method.invoke (собственный метод) в com. android .internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit. java: 886) в com. android .internal.os.ZygoteInit .main (ZygoteInit. java: 776)

Я не могу избавиться от этой ошибки уже около 7 дней ...: / Я знаю, что выложил слишком много кода, но я действительно не знаю, как ее решить ...

Вот мой EditProfileActivity.tk

    class EditProfileActivity : AppCompatActivity(), PasswordDialog.Listener {

    private lateinit var mViewModel: EditProfileViewModel
    private val TAG = "EditProfileActivity"
    private lateinit var mUser: User
    private lateinit var mPendingUser: User
    private lateinit var mFirebase: FirebaseHelper
    private lateinit var mCamera: CameraHelper


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_edit_profile)
        Log.d(TAG, "onCreate")

        mCamera = CameraHelper(this)
        close_image.setOnClickListener { finish() }
        save_image.setOnClickListener { updateProfile() }
        change_photo_text.setOnClickListener { mCamera.takeCameraPicture() }

        mFirebase = FirebaseHelper(this)

        mViewModel = ViewModelProviders.of(this).get(EditProfileViewModel::class.java)

        mViewModel.user.observe(this, Observer{it?.let{
            mUser = it
            name_input.setText(mUser.name)
            username_input.setText(mUser.username)
            website_input.setText(mUser.website)
            bio_input.setText(mUser.bio)
            email_input.setText(mUser.email)
            phone_input.setText(mUser.phone)
            profile_image.loadUserPhoto((mUser.photo))
        }})
    }

    @SuppressLint("MissingSuperCall")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == mCamera.REQUEST_CODE && resultCode == RESULT_OK) {
            mViewModel.uploadAndSetUserPhoto(mCamera.imageUri!!).addOnFailureListener {
                showToast(it.message)
            }
        }
    }

    private fun updateProfile() {
        mPendingUser = readInputs()
        val error = validate(mPendingUser)
        if (error == null) {
            if (mPendingUser.email == mUser.email) {
                updateUser(mPendingUser)
            } else {
                PasswordDialog().show(supportFragmentManager, "password_dialog")
            }
        } else {
            showToast(error)
        }
    }

    private fun readInputs(): User {
        return User(
            name = name_input.text.toString(),
            username = username_input.text.toString(),
            email = email_input.text.toString(),
            website = website_input.text.toStringOrNull(),
            bio = bio_input.text.toStringOrNull(),
            phone = phone_input.text.toStringOrNull()
        )
    }

    override fun onPasswordConfirm(password: String) {
        if (password.isNotEmpty()) {
            val credential = EmailAuthProvider.getCredential(mUser.email, password)
           mFirebase.reauthenticate(credential) {
                mFirebase.updateEmail(mPendingUser.email) {
                    updateUser(mPendingUser)
                }
            }
        } else {
            showToast(getString(R.string.enter_your_password))
        }
    }

    private fun updateUser(user: User) {
        val updatesMap = mutableMapOf<String, Any?>()
        if (user.name != mUser.name) updatesMap["name"] = user.name
        if (user.username != mUser.username) updatesMap["username"] = user.username
        if (user.website != mUser.website) updatesMap["website"] = user.website
        if (user.bio != mUser.bio) updatesMap["bio"] = user.bio
        if (user.email != mUser.email) updatesMap["email"] = user.email
        if (user.phone != mUser.phone) updatesMap["phone"] = user.phone

        mFirebase.updateUser(updatesMap) {
            showToast(getString(R.string.profile_saved))
            finish()
        }
    }

    private fun validate(user: User): String? =
        when {
            user.name.isEmpty() -> getString(R.string.please_enter_name)
            user.username.isEmpty() -> getString(R.string.please_enter_username)
            user.email.isEmpty() -> getString(R.string.please_enter_email)
            else -> null
        }
}

мой EditProfileViewModel.kt

    class EditProfileViewModel(private val repository: EditProfileRepository) : ViewModel() {
    val user: LiveData<User> = repository.getUser()

    fun uploadAndSetUserPhoto(localImage: Uri): Task<Unit> =
        repository.uploadUserPhoto(localImage).onSuccessTask{ downloadUrl ->
            repository.updateUserPhoto(downloadUrl!!)
        }
}

вот мой EditProfileRepository .kt

    interface EditProfileRepository {
    fun getUser(): LiveData<User>
    fun uploadUserPhoto(localImage: Uri): Task<Uri>
    fun updateUserPhoto(downloadUrl: Uri): Task<Unit>

}

class FirebaseEditProfileRepository : EditProfileRepository {
    override fun uploadUserPhoto(localImage: Uri): Task<Uri> =
        storage.child("users/${currentUid()!!}/photo").putFile(localImage).onSuccessTask {
            storage.child("users/${currentUid()!!}/photo").downloadUrl}.onSuccessTask {
            Tasks.forResult(it!!)
        }

    override fun updateUserPhoto(downloadUrl: Uri): Task<Unit> =
        database.child("users/${currentUid()!!}/photo").setValue(downloadUrl).toUnit()

    override fun getUser(): LiveData<User> =
        database.child("users").child(currentUid()!!).liveData().map {
            it.asUser()!!
        }
}

и, наконец, вот мой ViewModelFactory.kt

@Suppress("UNCHECKED_CAST")
class ViewModelFactory: ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(AddFriendsViewModel::class.java)){
            return AddFriendsViewModel(FirebaseAddFriendsRepository()) as T
        } else if (modelClass.isAssignableFrom(EditProfileViewModel::class.java)){
            return EditProfileViewModel(FirebaseEditProfileRepository()) as T
        }else {
            error("Unknown view model class $modelClass")
        }
    }

}

1 Ответ

3 голосов
/ 23 января 2020

EditProfileViewModel не имеет пустого конструктора. Таким образом, чтобы создать его экземпляр, вам нужно пройти через ViewModelFactory.

Вы написали фабрику, вам просто нужно вызвать ее.

Вместо

 mViewModel = ViewModelProviders.of(this).get(EditProfileViewModel::class.java)

запись

mViewModel = ViewModelProviders.of(this,
                ViewModelFactory())
                .get(EditProfileViewModel::class.java)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...