Idee
Idee

Reputation: 1977

LiveData is abstract android

I tried initializing my LiveData object and it gives the error: "LiveData is abstract, It cannot be instantiated"

LiveData listLiveData = new LiveData<>();

Upvotes: 11

Views: 5269

Answers (5)

E.M.
E.M.

Reputation: 4547

In a ViewModel, you may want to use MutableLiveData instead.

E.g.:

class MyViewModel extends ViewModel {
  private MutableLiveData<String> data = new MutableLiveData<>();

  public LiveData<String> getData() {
    return data;
  }

  public void loadData() {
    // Do some stuff to load the data... then
    data.setValue("new data"); // Or use data.postValue()
  }
}

Or, in Kotlin:

class MyViewModel : ViewModel() {
  private val _data = MutableLiveData<String>()
  val data: LiveData<String> = _data

  fun loadData() {
    viewModelScope.launch {
      val result = // ... execute some background tasks
      _data.value = result
    }
  }
}

Upvotes: 6

sud007
sud007

Reputation: 6161

I think much better way of achieving this is by using, what we call is a Backing Property, to achieve better Encapsulation of properties.

Example of usage:

private val _userPoints = MutableLiveData<Int>()// used as a private member

val userPoints: LiveData<Int>
    get() {
        return _userPoints 
    } //used to access the value inside the UI controller (Fragment/Activity). 

Doing so maintains an editable MutableLiveData private to ViewModel class while, the read-only version of it is maintained as a LiveData, with a getter that returns the original value.

P.S. - notice the naming convention for both fields, using an (_) underscore. This is not mandatory but advised.

Upvotes: 0

smdufb
smdufb

Reputation: 565

You need to use MutableLiveData and then cast it to its parent class LiveData.

public class MutableLiveData extends LiveData

[MutableLiveData is] LiveData which publicly exposes setValue(T) and postValue(T) method.

You could do something like this:

fun initializeLiveData(foo: String): LiveData<String> {
    return MutableLiveData<String>(foo)
}

So then you get:

Log.d("now it is LiveData", initializeLiveData("bar").value.toString())
// prints "D/now it is LiveData: bar"

Upvotes: 0

shubhamgarg1
shubhamgarg1

Reputation: 2015

Yes, you cannot instantiate it because it is an abstract class. You can try to use MutableLiveData if you want to set values in the live data object. You can also use Mediator live data if you want to observe other livedata objects.

Upvotes: 0

Lew  Perren
Lew Perren

Reputation: 1239

Since it is abstract (as @CommonsWare says) you need to extend it to a subclass and then override the methods as required in the form:

public class LiveDataSubClass extends LiveData<Location> {

}

See docs for more details

Upvotes: 4

Related Questions