LiveData

已棄用。

下方程式碼與stateflow大部分一模一樣。

唯讀 與 可存取

LiveData是唯讀,唯讀代表不可以修改,只能讀取。

MutableLiveData是可讀可寫,可以存取。

MutableLiveData僅能在 ViewModel 中修改變數。

LiveData提供給Activity來讀取ViewModel的MutableLiveData變數。

LiveData.observe()為觀察者,觀察MutableLiveData的資料是否有變更。

所以當MutableLiveData(可讀可寫)變數有任何修改,LiveData都會觀察到。

Activity,使用LiveData(唯讀)的observe(),監控是否有變更,有變更就要接收變更的值。

LifecycleOwner

Activity本身就有實作LifecycleOwner,Activity就是LifecycleOwner。

LiveData.observe()

第一個參數代入LifecycleOwner,第二個參數則是監控的資料。注意!不是it.value,it本身就是LiveData.value

LiveData.observe(LifecycleOwner) {
	it
}

postValue

MutableLiveData本身有getValue與setValue的功能。
postValue()是使用在Thread、協程中。
setValue()是使用在main Thread。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MutableLiveData<T> extends LiveData<T> {

    /**
     * Creates a MutableLiveData initialized with the given {@code value}.
     *
     * @param value initial value
     */
    public MutableLiveData(T value) {
        super(value);
    }

    /**
     * Creates a MutableLiveData with no value assigned to it.
     */
    public MutableLiveData() {
        super();
    }

    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

以下是LiveNumberModel,在ViewModel修改用MutableLiveData,變數_number用底線開頭。
Activity使用的是LiveData,僅有唯讀功能,變數number沒有底線開頭。
increase()方法用於Main Thread,更新畫面使用。
increaseThread()方法,使用的是postValue(),在IO Thread、非Main Thread中使用此方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class LiveNumberModel : ViewModel() {
  private val _number = MutableLiveData<Int>(0)
  val number: LiveData<Int> = _number
  fun increase() {
    _number.value++
  }
  fun increaseThread() {
    var temp = _number.value + 1
    _number.postValue(temp)
  }
}

在Activity使用IO協程,呼叫postValue()。
如果在IO協程中,呼叫increase(),App會閃退。

number是唯讀的LiveData,observe()是觀察者,this是Activity,Activity本身就是LifecycleOwner。
it是LiveData.value。

1
2
3
viewModel.number.observe(this) {
    textv.text = it.toString()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MainActivity12 : AppCompatActivity() {
  private val viewModel by viewModels<LiveNumberModel>()
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val submit = findViewById<Button>(R.id.button)
    val textv = findViewById<TextView>(R.id.textView)
    viewModel.number.observe(this) {
      textv.text = it.toString()
    }
    submit.setOnClickListener {
      GlobalScope.launch(Dispatchers.IO) {
        viewModel.increaseThread()
        //viewModel.increase()
      }
    }
  }
}

LiveData與retrofit

請先查看retrofit文章,再往下繼續看下去。

LiveViewModel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.coroutine.api.ArticleList
import androidx.lifecycle.viewModelScope
import com.example.coroutine.api.ArticleApi
import kotlinx.coroutines.launch

class LiveViewModel : ViewModel() {
  private val _articleList = MutableLiveData<ArticleList>()
  val articleList: LiveData<ArticleList> = _articleList
  fun getArticleList() {
    viewModelScope.launch {
      val result = ArticleApi.retrofit.articleList()
      _articleList.value = result
    }
  }
}

Activity使用Livedata

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import com.example.coroutine.R
import com.example.coroutine.model.LiveViewModel


class MainActivity11 : AppCompatActivity() {
  private val viewModel by viewModels<LiveViewModel>()
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val submit = findViewById<Button>(R.id.button)
    val textv = findViewById<TextView>(R.id.textView)
    viewModel.articleList.observe(this) {
      textv.text = it.toString()
    }
    submit.setOnClickListener {
      viewModel.getArticleList()
    }
  }
}

results matching ""

    No results matching ""