【问题标题】:ViewModel not observed by AppCompatActivityAppCompatActivity 未观察到 ViewModel
【发布时间】:2018-12-12 09:35:18
【问题描述】:

我正在尝试在我的 EarthquakeActivity 中同时使用 ViewModel,但我不断收到此错误:

Wrong 1st argument type. Found: 'com.example.android.quakereport.EarthquakeActivity', required: 'androidx.lifecycle.LifecycleOwner'

这是我尝试做的时候

mainViewModel.getEarthquakeData().observe(this, new Observer<List<Earthquake>>() {
        @Override
        public void onChanged(List<Earthquake> earthquakes) {
                // do something
        }
    });

作为活动的this返回错误。

我读到hereAppCompatActivity 已经扩展了 LifecycleOwner,这正是我正在使用的。这里有什么问题?其他所有教程都没有这个问题。

我的EarthquakeActivity.java

package com.example.android.quakereport;

import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

import POJO.Earthquake;
import POJO.RootEarthquakeResponse;
import androidx.lifecycle.Observer;
import retrofit2.Call;


public class EarthquakeActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private RecyclerView.Adapter adapter;
    private LinearLayoutManager  layoutManager;

    public static final String LOG_TAG = EarthquakeActivity.class.getName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.earthquake_activity);

        // Create a fake list of earthquake locations.
        final ArrayList<Earthquake> earthquakes = getEarthquakes();

        setupRecyclerView(earthquakes); // set up recycler view

        MainViewModel mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
        mainViewModel.getEarthquakeData().observe(this, new Observer<List<Earthquake>>() {
            @Override
            public void onChanged(List<Earthquake> earthquakes) {
                    // do something
            }
        });

    }

    private void setupRecyclerView(ArrayList<Earthquake> earthquakes){
        // set up recyclerview
    }
}

我的 MainViewModel:

package com.example.android.quakereport;

import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import POJO.Earthquake;
import POJO.Feature;
import POJO.RootEarthquakeResponse;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainViewModel extends AndroidViewModel {

    private MutableLiveData<List<Earthquake>> earthquakeLiveData;
    private String LOG_TAG = MainViewModel.class.getName();

    public MainViewModel(@NonNull Application application) {
        super(application);
//        earthquakeLiveData = new EarthquakeLiveData();
    }

    public LiveData<List<Earthquake>> getEarthquakeData(){
        if (earthquakeLiveData == null){
            earthquakeLiveData = new MutableLiveData<>();
            loadEarthquakes();
        }

        return earthquakeLiveData;
    }

    private void loadEarthquakes(){
        EarthquakeService earthquakeService = EarthquakeServiceGenerator.createService(EarthquakeService.class);

        Call<RootEarthquakeResponse> call = earthquakeService.getEarthquakes("geojson", "time", 6, 10);

        call.enqueue(new Callback<RootEarthquakeResponse>() {
            @Override
            public void onResponse(Call<RootEarthquakeResponse> call, Response<RootEarthquakeResponse> response) {
                List<Earthquake> earthquakes = new ArrayList<>();
                for (Feature f: response.body().getFeatures()) {
                    earthquakes.add(f.getEarthquake());
                }

                earthquakeLiveData.setValue(earthquakes);
                Log.d(LOG_TAG, "Successful!");
                Log.d(LOG_TAG, response.body().toString());
            }

            @Override
            public void onFailure(Call<RootEarthquakeResponse> call, Throwable t) {
                Log.e(LOG_TAG, call.request().toString()); // check request if failed
                Log.e(LOG_TAG, t.toString()); // check error
            }
        });
    }
}

这是我的 gradle 依赖项:

implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:recyclerview-v7:26.1.0'
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1'

implementation "androidx.lifecycle:lifecycle-viewmodel:2.0.0" // use -ktx for Kotlin
// alternatively - just LiveData
implementation "androidx.lifecycle:lifecycle-livedata:2.0.0"
implementation "android.arch.lifecycle:extensions:1.1.1"

我是否需要处理覆盖生命周期或我的依赖项有问题?

【问题讨论】:

  • com.android.support:appcompat-v7:26.1.0 替换为androidx.appcompat:appcompat:1.0.0,将com.android.support:recyclerview-v7:26.1.0 替换为androidx.recyclerview:recyclerview:1.0.0
  • 使用 ViewModel 而不是 AndroidViewModel

标签: java android gradle viewmodel android-architecture-components


【解决方案1】:

您正在使用 AndroidX 库中的 ViewModel,并且还使用了 AppCompatActivity 的支持库。

将您的支持库迁移到 AndroidX 以解决您的问题。

【讨论】:

  • 任何方便的资源如何做到这一点?
  • 使用android studio 3.2.1及以上版本,具有迁移到AndroidX功能。
  • @DonovanKeating 检查这个:developer.android.com/jetpack/androidx/migrate
  • 这行得通!罪魁祸首一直是 Android X!
【解决方案2】:

从 AndroidX 库中导入 AppCompatActivity:

import androidx.appcompat.app.AppCompatActivity

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    • 2022-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多