Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AppCompatActivity not implementing LifecycleOwner

I am using Android Support Library 26.1.0. These are the dependencies in app module -

implementation "android.arch.lifecycle:runtime:1.0.0"
implementation "android.arch.lifecycle:extensions:1.0.0-beta1"
implementation "android.arch.persistence.room:rxjava2:1.0.0-beta1"
implementation "android.arch.lifecycle:common-java8:1.0.0-beta1"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0-beta1"

But when I am trying to use ViewModel like below -

mUserViewModel.getUsers().observe(this,
            (Observer<Resource<List<UserView>>>) listResource -> {
                if(listResource != null){
                    this.handleDataState(listResource.status, listResource.data, listResource.message);
                }
            });

It is showing error at this and the error message is Wrong first argument type Found: packagename.BrowseActivity, required: android.arch.lifecycle.LifecycleOwner. (Although support library version is 26.1+ which already implements LifecycleOwner)

I have also tried to implement LifecycleRegistryOwner which I found in this sample and this is also not working. Kindly suggest a solution and let me know if I am doing anything wrong.

Edit 1 - This is Activity class

import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ProgressBar;

import com.github.amitkma.boilerplate.app.R;
import com.github.amitkma.boilerplate.app.mapper.UserMapper;
import com.github.amitkma.boilerplate.app.model.UserModel;
import com.github.amitkma.boilerplate.app.ui.widget.EmptyView;
import com.github.amitkma.boilerplate.app.ui.widget.ErrorView;
import com.github.amitkma.boilerplate.presentation.data.Resource;
import com.github.amitkma.boilerplate.presentation.data.ResourceState;
import com.github.amitkma.boilerplate.presentation.factory.ViewModelFactory;
import com.github.amitkma.boilerplate.presentation.viewmodel.UserViewModel;
import com.github.amitkma.boilerplate.presentation.vo.UserView;

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

import javax.inject.Inject;

import dagger.android.AndroidInjection;

public class BrowseActivity extends AppCompatActivity {

    @Inject
    UserAdapter mUserAdapter;
    @Inject
    UserMapper mUserMapper;
    @Inject
    ViewModelFactory mViewModelFactory;
    private UserViewModel mUserViewModel;

    private RecyclerView mRecyclerView;
    private ProgressBar mProgressBar;
    private ErrorView mErrorView;
    private EmptyView mEmptyView;


   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       AndroidInjection.inject(this);
       setContentView(R.layout.activity_browse);
       mUserViewModel = ViewModelProviders.of(this, mViewModelFactory)
            .get(UserViewModel.class);

       mRecyclerView = findViewById(R.id.recycler_browse);
       mProgressBar = findViewById(R.id.progress);
       mEmptyView = findViewById(R.id.view_empty);
       mErrorView = findViewById(R.id.view_error);

       setupBrowseRecycler();
       setupViewListeners();
   }

    @Override
    protected void onStart() {
        super.onStart();
        mUserViewModel.getUsers().observe(this,
            (Observer<Resource<List<UserView>>>) listResource -> {
                if(listResource != null){
                    this.handleDataState(listResource.status, listResource.data, listResource.message);
                }
            });
    }
    ....
}

This is ViewModel Class

import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;

import com.github.amitkma.boilerplate.domain.interactor.GetUserList;
import com.github.amitkma.boilerplate.domain.model.User;
import com.github.amitkma.boilerplate.presentation.data.Resource;
import com.github.amitkma.boilerplate.presentation.data.ResourceState;
import com.github.amitkma.boilerplate.presentation.mapper.UserMapper;
import com.github.amitkma.boilerplate.presentation.vo.UserView;

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

import javax.inject.Inject;

import io.reactivex.subscribers.DisposableSubscriber;

public class UserViewModel extends ViewModel {

    private final GetUserList mGetUserList;
    private final UserMapper mUserMapper;

    @Inject
    public UserViewModel(GetUserList getUserList,
            UserMapper userMapper) {
        mGetUserList = getUserList;
        mUserMapper = userMapper;
        fetchUsers();
    }

    public void fetchUsers(){
        mUserMutableLiveData.postValue(new Resource(ResourceState.LOADING, null, null));
        mGetUserList.execute(new UserSubscriber(), null);
    }

    public LiveData<Resource<List<UserView>>> getUsers(){
        return mUserMutableLiveData;
    }

    @Override
    protected void onCleared() {
        mGetUserList.dispose();
        super.onCleared();
    }

    private final MutableLiveData<Resource<List<UserView>>> mUserMutableLiveData =
        new MutableLiveData<>();

}

like image 640
Amit Kumar Avatar asked Sep 28 '17 08:09

Amit Kumar


People also ask

How do you use LifecycleOwner?

Every Activity has a Lifecycle. This Activity will be a Lifecycle Owner(any activity or fragment can be called a lifecycle owner). When an activity is initialized LifecycleOwner is the one that will be constructed initially. Any class that implements the LifeCycleOwner interface indicates that it has Android LifeCycle.

How can you make a class lifecycle-aware in Android implement LifecycleOwner?

Step 1: Define LiveData object to store data and a method to observe that data in View class. Step 3: Define viewModel object in activity. this refers to an instance of lifecycleOwner . We are observing Data changes in activity so activity will be notified when live data has been set.

Is ViewModel Life Cycle Aware?

Lifecycle Awareness: ViewModel objects are also lifecycle-aware. They are automatically cleared when the Lifecycle they are observing gets permanently destroyed.

How many types of LifecycleOwner available in fragment when and which LifecycleOwner should pass?

When using a ViewModel exposing LiveData s for a Fragment , there are currently two LifecycleOwners that can be used to oberve: the Fragment itself or. the Fragment 's property mViewLifecycleOwner .


2 Answers

Same problem here, so I had to update my androidx.appcompat dependency, like below:

implementation 'androidx.appcompat:appcompat:1.1.0-alpha04'
like image 198
Thales Pupo Araujo Avatar answered Nov 10 '22 04:11

Thales Pupo Araujo


You don't need to implement this anymore.

Just extend your activity by AppCompatActivity which extends LifecycleOwner.

This interface was deprecated in API level 1.0.0. Use android.support.v7.app.AppCompatActivity which extends LifecycleOwner, so there are no use cases for this class.

You forgot to override

private final LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);

@Override
public LifecycleRegistry getLifecycle() {
    return lifecycleRegistry;
}

You need at least Support-Lib 26.1

Same for fragments. Just extend your Fragment by LifecycleFragment which extends android.support.v4.app.Fragment

Edit: Just rebuilt a quick sample project using Kotlin and it worked.

class MainActivity : AppCompatActivity(), HasSupportFragmentInjector, AnkoLogger {
    private val lifecycleRegistry by lazy { android.arch.lifecycle.LifecycleRegistry(this) }
    private val viewModel by lazy { ViewModelProviders.of(this, viewModelFactory).get(BridgesVm::class.java) }
    override fun getLifecycle() = lifecycleRegistry

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModel.data.observe(this, Observer<Bridge?> { info { "Received" } })
   }
}

class BridgesVm @Inject constructor() : ViewModel() { 
        val data: LiveData<Bridge> = MutableLiveData<Bridge>()
}

Edit:

There's a problem using arch version beta1. Consider using 1.0.0-alpha9-1 until this is fixed. In my case it wasnt working if i use beta1 but working with alpha 9-1

like image 30
Emanuel S Avatar answered Nov 10 '22 03:11

Emanuel S