簡體   English   中英

ViewModel 沒有零參數構造函數錯誤 - 即使它具有零參數構造函數

[英]ViewModel has no zero argument constructor error - even when it has a zero argument constructor

我是 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);
    }
}

我犯了同樣的錯誤。 以下是我的應用級 build.gradle 中的依賴項:

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 以存儲用戶位置的 class...

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();
        }
    }

還有一個 class 擴展 ViewModel 以允許主要活動到達 LocationLiveData。

 public class LocationViewModel extends ViewModel {
        private LocationLiveData locationLiveData;

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

        public LocationLiveData getLocationLiveData() {
            return locationLiveData;
        }
    }

然后,當我嘗試在 onMapReady 方法中創建 locationViewModel 的實例時:

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

我在該行收到錯誤:

無法創建 class com.example.MapsActivity$LocationViewModel 的實例

原因:java.lang.InstantiationException:java.lang.Class 沒有零參數構造函數

即使我完全在 locationViewModel 中取出構造函數,並且如果我嘗試擴展 AndroidViewModel,我也會收到此錯誤。

有任何想法嗎? 我見過其他類似的查詢,但答案始終是將 arguments 從構造函數中取出 - 我已經完成了!

非常感謝您的幫助

在使用刀柄時,當我忘記添加時我面臨同樣的問題

@AndroidEntryPoint

活動聲明上方

當你寫

public class MainActivity extends AppCompatActivity {

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

這使得MyViewModel成為MainActivity的內部 class ,這意味着它對外部 class 具有隱式引用(根據Java 文檔),並且不能與MainActivity分開構造。 這實際上意味着在字節碼中,它的構造函數總是采用MainActivity的一個實例——即使你沒有寫出那個構造函數。

您可以通過添加static關鍵字使您的內部 class 成為 static 嵌套 class。 這將刪除對外部 class 的隱式引用,並使其類似於任何其他頂級 class:

public class MainActivity extends AppCompatActivity {

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

任何一個:

  • MyViewModel移動到單獨的 Java 文件,或

  • 使MyViewModel成為static class

現在,您已將MyViewModel定義為MainActivity的內部 class 。 那是行不通的,因為只有MainActivity的實例可以創建MyViewModel的實例。 特別是, ViewModelProvider不能創建MyViewModel的實例。

就我而言,確實忘記將HasSupportFragmentInjector添加到我的Activity中!

public class MainActivity extends AppComaptActivity
        implements HasSupportFragmentInjector{


@Override
public void onCreate(Bundle savedInstanceState) {
    AndroidInjection.inject(this);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    @Inject
    DispatchingAndroidInjector<Fragment> fragmentDispatchingAndroidInjector;


    @Override
    public AndroidInjector<Fragment> supportFragmentInjector() {
        return fragmentDispatchingAndroidInjector;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM