当前位置: 首页 > 知识库问答 >
问题:

ViewModel没有零参数构造函数错误-即使它具有零参数构造函数

邬宏扬
2023-03-14

我是新的Android和Java,并试图使基于位置的应用程序。

编辑

我做了一个非常非常简单的测试代码,得到了同样的错误。这是java:

package com.example.viewmodeltest;

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    public class MyViewModel extends ViewModel {
        public int scoreTeamA = 0;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyViewModel locationViewModel = new ViewModelProvider(this).get(MyViewModel.class);
    }
}

我也犯了同样的错误。以下是我的应用程序级构建中的依赖项。格雷德尔:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    //dependencies for ViewModel, LiveData, etc.
    def lifecycle_version = "2.2.0"
    def arch_version = "2.1.0"

    // ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
    // LiveData
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    // Lifecycles only (without ViewModel or LiveData)
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
    // Saved state module for ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
    // Annotation processor
    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
}

原帖

我试图使用ViewModel和LiveData来更新用户位置,因为我知道这是生命周期感知的最佳方式。我有一个默认的地图活动...

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {...}

一个扩展LiveData以存储用户位置的类。。。

public class LocationLiveData extends LiveData<Location> {
        private final Context context;
        private FusedLocationProviderClient fusedLocationClient;
        private LocationRequest locationRequest;

        public LocationLiveData(Context context) {
            this.context = context;
            this.fusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
        }

        private void setLocationData(Location location) {
            Location value = new Location("SetInternal");
            value.setLatitude(location.getLatitude());
            value.setLongitude(location.getLongitude());
            setValue(value);
        }

        protected void createLocationRequest() {
            LocationRequest locationRequest = LocationRequest.create();
            locationRequest.setInterval(1000);
            locationRequest.setFastestInterval(500);
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        }

        private LocationCallback locationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                if (locationResult == null) {
                    return;
                }
                for (Location location : locationResult.getLocations()) {
                    setLocationData(location);
                }
            }
        };

        private void startLocationUpdates() {
            createLocationRequest();
            fusedLocationClient.requestLocationUpdates(locationRequest,
                    locationCallback,
                    Looper.getMainLooper());
        }

        @Override
        protected void onInactive() {
            super.onInactive();
            fusedLocationClient.removeLocationUpdates(locationCallback);
        }

        @Override
        protected void onActive() {
            super.onActive();
            fusedLocationClient.getLastLocation()
                    .addOnSuccessListener(new OnSuccessListener<Location>() {
                        @Override
                        public void onSuccess(Location location) {
                            if (location != null)
                                setValue(location);
                        }
                    });
            startLocationUpdates();
        }
    }

以及一个扩展ViewModel的类,该类允许主要活动访问LocationLiveData。

 public class LocationViewModel extends ViewModel {
        private LocationLiveData locationLiveData;

        public LocationViewModel () {
            locationLiveData = new LocationLiveData(getApplicationContext());
        }

        public LocationLiveData getLocationLiveData() {
            return locationLiveData;
        }
    }

然后当我尝试在onMap就绪方法中创建locationViewModel的实例时:

LocationViewModel locationViewModel = new ViewModelProvider(this).get(LocationViewModel.class);

我在那一行有个错误:

无法创建类com.example.MapsActive$LocationViewModel的实例

原因:java。实例化异常:java。类没有零参数构造函数

即使我完全在locationViewModel中取出构造函数,并且尝试扩展AndroidViewModel,我也会出现这个错误。

有什么想法吗?我见过其他类似的查询,但答案总是从构造函数中取出参数——我已经这样做了!

非常感谢任何帮助

共有3个答案

叶裕
2023-03-14

当你写作的时候

public class MainActivity extends AppCompatActivity {

    public class MyViewModel extends ViewModel {
       public int scoreTeamA = 0;
    }
}

这使得MyViewModel成为MainActivity的一个内部类,这意味着它有一个对外部类的隐式引用(根据Java文档),并且不能与MainActivity分开构造。这实际上意味着在字节码中,它的构造函数总是采用main活动的一个实例——即使你没有写出这个构造函数。

通过添加static关键字,可以使内部类成为静态嵌套类。这将删除对外部类的隐式引用,并使其与任何其他顶级类类似:

public class MainActivity extends AppCompatActivity {

    public static class MyViewModel extends ViewModel {
       public int scoreTeamA = 0;
    }
}
谭翔
2023-03-14

要么:

>

  • MyViewModel移动到单独的Java文件,或

    使MyViewModel成为静态类

    现在,您已经将MyViewModel定义为MainActivity的一个内部类。这将不起作用,因为只有MainActivity的实例才能创建MyViewModel的实例。尤其是,ViewModelProvider无法创建MyViewModel的实例。

  • 钱志强
    2023-03-14

    在使用刀柄时,我也遇到了同样的问题,因为我忘了添加

    @AndroidEntryPoint
    

    在活动声明上方

     类似资料:
    • 我正在尝试使用recyclerview和room库创建一个简单的ToDoList应用程序。在使用room和mvvm架构方面,我正在遵循android开发者代码实验室,我似乎遇到了困难。我已经设置了应用程序的每一层,但在尝试使用ViewModelProvider实例化ViewModel时出现了一个错误。下面是我的ViewModel类中的代码。 } 下面是我试图初始化ViewModel的main片段中

    • 我通过本文档了解LiveData和ViewModel。在文档中,ViewModel类具有构造函数, 但是,当我运行代码时,会出现异常: 原因:java.lang.运行时异常:无法创建类的实例UserViewModel原因:java.lang.实例异常:java.lang.类没有零参数构造函数

    • 我正在使用并试图将我的导入我的类。 当使用ViewModel查看Google的hilt文档时,我们可以看到他们能够将注入到所述

    • 我想启动一项服务,我使用: 启动它: 我的应用崩溃后,logcat返回: java.lang.Class 在 android.app.活动线程.handle上没有零参数构造函数创建服务(活动线程.java:3201) 在 android.app.活动线程.-wrap5(活动线程.java) 在 android.app.活动线程$H.handleMessage(活动线程.java:1586) 在 a

    • 注:在标记为副本之前,请仔细阅读。我已经尝试了所有现有的答案。 我在用匕首2。 视图模型实例已在活动中成功创建,但当我从同一活动中打开BottomSheet对话框时,无法创建实例。 日志: 用户界面。搜索viewmodel。SearchViewModel

    • 我手动将我的应用程序从dagger2迁移到了刀柄。我没有遇到任何编译或构建错误。但当我尝试运行我的应用程序时,它会在启动屏幕上崩溃: 它说它不能创建那个viewmodel的实例,因为它没有零参数构造函数,但是:1-我的viewmodel类是用hilt注入的(BaseViewModel是抽象的): 2-我的活动用Android Entry Point注释(Base活动是抽象的): 3-视图模型所依赖