Ich versuche, eine Beispiel-App mit Android-Architekturkomponenten zu schreiben, aber selbst nach tagelangen Versuchen konnte ich sie nicht zum Laufen bringen. Es gibt mir die obige Ausnahme.
Lebenszyklusbesitzer: -
public class MainActivity extends LifecycleActivity {
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv_user);
PostViewModel viewModel = ViewModelProviders.of(this).get(PostViewModel.class);
viewModel.loadPosts();
viewModel.getPost().observe(this, new Observer<Post>() {
@Override
public void onChanged(@Nullable Post post) {
if(post != null) {
textView.setText(post.toString());
}
}
});
}
}
ViewModel: -
public class PostViewModel extends ViewModel {
private MediatorLiveData<Post> post;
private PostRepository postRepo;
PostViewModel() {
post = new MediatorLiveData<>();
postRepo = new PostRepository();
}
public LiveData<Post> loadPosts() {
post.addSource(postRepo.getPost(),
post -> this.post.setValue(post)
);
return post;
}
@NonNull
public LiveData<Post> getPost() {
return post;
}
}
android
mvvm
android-architecture-components
Parag Kadam
quelle
quelle
Wenn Sie verwenden
Hilt
, stellen Sie sicher, dass Ihre Aktivität / Ihr Fragment mit@AndroidEntryPoint
Anmerkungen versehen istquelle
Cannot create an instance of class ViewModel
Laufzeit zum Absturz führt.Stellen Sie sicher, dass Ihr
ViewModel
Konstruktor nur einen Parameter hat, dApplication
. H.Beispiel:
quelle
Wenn Sie verwenden,
Kotlin
stellen Sie sicher , jeder ersetzenannotationProcessor
inbuild.gradle
mitkapt
.Mögen:
annotationProcessor "android.arch.persistence.room:compiler:$rootProject.roomVersion"
Wird werden
kapt "android.arch.persistence.room:compiler:$rootProject.roomVersion"
und hinzufügen
apply plugin: 'kotlin-kapt'
oben auf derbuidl.gradle
Datei.Anmerkungsverarbeitung mit Kotlin
quelle
Ich hatte dieses Problem nach Googles roomdb CodeLab . Die Lösung änderte Folgendes.
Bearbeitet
Fügen Sie der Gradle-Datei die folgenden Build-Abhängigkeiten hinzu (Stand 22.02.2020)
Importe innerhalb des Fragments
ViewModel erstellen. Fügen Sie eine der folgenden Methoden hinzu.
Hinweis : Ich habe dies auf viele Arten gesehen. Ich glaube, der richtige Weg ist
getDefaultViewModelProviderFactory()
. Aber ich habe benutztrequireActivity()
.|
ViewModelProvider-Dokumente
quelle
Es gibt nur wenige Gründe, die Ausnahme auszulösen. Ich habe einige von ihnen erwähnt.
Stellen Sie sicher, dass der Konstruktor Ihrer Ansichtsmodellklasse öffentlich ist
Stellen Sie sicher, dass Sie die Abhängigkeit für den Lebenszyklus in Ihrer Gridle-Datei hinzugefügt haben, auch wenn Sie den von Ihnen hinzugefügten Raum und andere Bibliotheken verwenden.
quelle
Es war mir nicht ganz klar, aber als ich diesen Fehler bekam, habe ich ihn durch Erstellen eines öffentlichen Konstruktors behoben. Mein Konstruktor wurde aus den Android Developer-Beispielen abgeleitet und enthielt das Repository als Parameter. Durch das Erstellen eines zusätzlichen Konstruktors, der ohne Parameter leer war, und dessen Veröffentlichung wurde das Problem behoben.
dh in Ihrem Fall
public PostViewModel() {}
quelle
Machen Sie die Klasse und den Konstruktor öffentlich, es hat mein Problem gelöst.
quelle
Wenn Sie in Ihrer Aktivität das Ansichtsmodell verwendet haben, überprüfen Sie, ob Ihre Aktivität "DaggerAppCompatActivity" erweitert oder nicht
Zum Beispiel
Ändern Sie dies in
quelle
quelle
public
.Erweitern Sie AndroidViewModel aus Ihrer ViewModel-Klasse.
quelle
Wenn Sie Hilt verwenden, vergessen Sie nicht, diese vier Abhängigkeiten hinzuzufügen.
Hinweis: - Wenn eine dieser Abhängigkeiten fehlt, wird eine
Cannot create an instance of class ViewModel
Fehlermeldung angezeigtquelle
Ich habe dies nach der Migration auf AndroidX erhalten.
Es gibt einen Fehler, bei
androidx.lifecycle:lifecycle-viewmodel:2.0.0-beta01
dem Proguard den Konstruktor entfernt.https://issuetracker.google.com/issues/112230489
Beheben Sie das Problem durch ein Upgrade auf 2.0.0 und denken Sie daran, Ihre Proguard-Regeln bei Bedarf zu aktualisieren.
Meine Fehlermeldung sah folgendermaßen aus:
java.lang.RuntimeException: Cannot create an instance of class my.custom.viewmodel.CustomViewModel at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:202) at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135) at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103) ...... Caused by: java.lang.NoSuchMethodException: <init> [class android.app.Application] at java.lang.Class.getConstructor0(Class.java:2204) at java.lang.Class.getConstructor(Class.java:1683) at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:200) ... 34 more androidx.test.espresso.PerformException: Error performing 'single click - At Coordinates: 539, 1167 and precision: 16, 16' on view 'with id: my.test:id/button_return_to_main_menu'. at androidx.test.espresso.PerformException$Builder.build(PerformException.java:82) at androidx.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:79) ..... Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{my.custom.domain.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class my.custom.viewmodel.CustomViewModel at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
quelle
Wenn Ihre PostViewModel-Klasse eine innere Klasse ist, stellen Sie sicher, dass sie öffentlich und statisch ist
quelle
In meinem Fall war es ein Abhängigkeitsproblem.
Wenn Sie Livedata verwenden ,,
build.gradle (Module.app)
nicht
benutze diese
quelle
DggerHilt kann auch der Grund sein, wenn Sie verwenden es sicherstellen , dass Ihr
activity/fragment
wird mit@AndroidEntryPoint
Anmerkung auf sie.quelle
In meinem Fall war der Grund, dass ich zu früh versucht habe, eine gemeinsam genutzte Instanz des ViewModel in meinem Fragment abzurufen - bevor die Aktivität erstellt wurde. Was passiert, wenn die Anwendung nach dem Beenden ihren Status wiederherstellt?
Voraussetzungen :
Code in Aktivität:
Code in Fragment:
Wenn ich die App zum ersten Mal öffne, funktioniert alles einwandfrei: Aktivität erstellt eine Instanz von ViewModel; Ich öffne Fragment, das die Instanz von ViewModel erhält. Wenn die Anwendung jedoch versucht, ihren Status nach dem Beenden wiederherzustellen, ruft sie zuerst den Hauptteil von onCreate des Fragments und dann den Hauptteil von onCreate der Aktivität auf. Zu diesem Zeitpunkt kann das Fragment das ViewModel nicht abrufen, da Activity es noch nicht erstellt hat.
Lösung 1 : Verschieben Sie den Code, wenn das Fragment das ViewModel von onCreate nach onViewCreated erhält. Dies ist in Ordnung, da ich alle Live-Daten auch in onViewCreated beobachte.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel = activity?.run { ViewModelProviders.of(this)[MapViewModel::class.java] } ?: throw Exception("Invalid Activity") viewModel.getSurveyDateLiveData().observe(viewLifecycleOwner, Observer<String> { dateTextView.text = it }) ... }
Lösung 2 : Erstellen Sie die Instanz von ViewModel in Activity.onCreate, bevor super.onCreate aufgerufen wird. In diesem Fall können Sie das ViewModel in onCreate Ihres Fragments abrufen .
Lösung 3 :
Wenn Sie eine Repository-Instanz in Ihr ViewModel einfügen, überprüfen Sie, ob Sie
@Inject constructor(...): ViewModel()
Ihr Repository nicht zum Einfügen verwenden, sondern**@ViewModelInject constructor(...): ViewModel()**
quelle
In meinem Fall musste ich eine ListItemViewModelFactory verwenden, um einen Parameter an mein Ansichtsmodell zu übergeben.
quelle
Mein Problem war, dass die IDE meiner ViewModel-Klasse einen " abstrakten " Modifikator hinzugefügt hatte .
quelle
Machen Sie die ViewModal-Klasse und die Konstruktion öffentlich
quelle
Wenn der Konstruktor Ihres Ansichtsmodells öffentlich ist und nur Anwendungen akzeptiert, stellen Sie sicher, dass Sie Ihr eigenes Modell ohne erstellen können
ViewModelProvider
. Die Fehlermeldung ist möglicherweise viel deutlicher:quelle
Ich bin ein erfahrener Android-Entwickler und habe ViewModel 100 Mal ohne Probleme verwendet. Heute bin ich auf dieses Problem gestoßen. Verbrachte Stunden und blätterte durch verschiedene SO-Beiträge. Wurde nicht gelöst.
Dann habe ich gesehen, dass der Paketname, in dem ich das ViewModel habe, enthält
new
. So was:com.myapp.myfeature.new.feature
Ich
new
habeneww
zum Testen wie folgt gewechselt :com.myapp.myfeature.neww.feature
und es hat funktioniert! Ich hoffe, jemand findet es nützlich.
quelle
Ich verwende dieses Beispiel der Android-Arcuitecture-Komponente BasicSample , um ein neues Projekt mit einem ähnlichen Fehlerprotokoll zu erstellen, bei dem festgestellt wurde, dass ich den Anwendungsnamen nicht geändert habe
und das war mein Fehler, um den Namen aplicacion in de BasicApp zu setzen, ist diese Klasse im Beispiel implementiert.
... <application android:name=".BasicApp" android:allowBackup="false"
quelle
Bitte fügen Sie den folgenden Code hinzu. Es hat bei mir funktioniert
quelle