【发布时间】:2019-01-18 20:14:09
【问题描述】:
我有一个 LiveData 对象,我在活动的片段中观察它。该活动通过 2 个广播接收器侦听来自系统的广播。根据当前日期从房间查询数据。因此接收器检测日期是否已更改,如果已更改,则继续刷新查询。
问题是在我更改设置中的日期并返回应用程序后,没有触发观察者。如果我去另一个片段并返回数据会改变,但不是来自
现在是代码:
活动:
private lateinit var timeReceiver: MyTimeReceiver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
timeReceiver = MyTimeReceiver()
registerReceiver(timeReceiver, filter)
registerReceiver(refreshReceiver, IntentFilter("refresh_data"))
mainFragment = MainFragment.newInstance()
}
private val refreshReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == "refresh_data") {
Timber.e("time changed, need to refresh data")
mainFragment.refreshData()
}
}
}
override fun onDestroy() {
super.onDestroy()
unregisterReceiver(timeReceiver)
unregisterReceiver(refreshReceiver)
}
片段:
private var counter: Int = 0
private lateinit var viewModel: MainFragmentViewModel
private lateinit var date: String
companion object {
fun newInstance(): MainFragment {
return MainFragment()
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_main, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
plus_btn.setOnClickListener { addCup() }
minus_btn.setOnClickListener { decreaseCup() }
viewModel = ViewModelProviders.of(this).get(MainFragmentViewModel::class.java)
viewModel.dataList.observe(viewLifecycleOwner, Observer {
it.let { it1 ->
counter = it1.size
cup_counter.text = "$counter"
setGoalVisibility()
}
})
}
override fun onResume() {
super.onResume()
viewModel.checkCups(setDate())
}
private fun decreaseCup() {
viewModel.deleteCup(counter, date)
}
private fun addCup() {
Timber.e(date)
viewModel.insertCup(
WaterCupEntity(
System.currentTimeMillis(),
++counter,
date
)
)
}
fun refreshData() {
viewModel.checkCups(setDate())
}
private fun setDate(): String {
val dateFormat = SimpleDateFormat("dd.MM.yyyy", Locale.US)
date = dateFormat.format(Calendar.getInstance().time)
return date
}
视图模型:
class MainFragmentViewModel(application: Application) : AndroidViewModel(application) {
private var dao: WaterCupDao
var dataList: LiveData<List<WaterCupEntity>>
private var job = Job()
private val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
private val scope = CoroutineScope(coroutineContext)
private val dateFormat: SimpleDateFormat = SimpleDateFormat("dd.MM.yyyy", Locale.US)
var date: String
init {
dao = MyCupsDb.getInstance(application, scope).getDao()
date = dateFormat.format(Calendar.getInstance().time)
Timber.e("getting all cups for date: %s", date)
dataList = dao.getAllCupsWithSameDate(date)
}
fun checkCups(date :String) {
dataList = dao.getAllCupsWithSameDate(date)
}
fun insertCup(cup: WaterCupEntity) = runBlocking {
scope.launch(Dispatchers.IO) {
dao.insert(cup)
}
}
fun deleteCup(number: Int, date: String) =
scope.launch(Dispatchers.IO) {
dao.deleteCupForDate(number, date)
}
fun deleteToday(date :String) {
scope.launch (Dispatchers.IO){
dao.deleteAllCupsForDate(date)
}
}
fun deleteAllCups() {
scope.launch (Dispatchers.IO){
dao.deleteAllCups()
}
}
}
房间数据库:
@Database(entities = [WaterCupEntity::class], version = 1)
abstract class MyCupsDb : RoomDatabase() {
abstract fun getDao(): WaterCupDao
companion object {
@Volatile
private var instance: MyCupsDb? = null
fun getInstance(context: Context, scope:CoroutineScope): MyCupsDb {
return instance ?: synchronized(this) {
instance ?: buildDb(context,scope).also { instance = it }
}
}
private fun buildDb(context: Context,scope:CoroutineScope): MyCupsDb {
return Room.databaseBuilder(context, MyCupsDb::class.java, "myDb")
.addCallback(WordDatabaseCallback(scope))
.build()
}
}
private class WordDatabaseCallback(
private val scope: CoroutineScope
) : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onOpen(db)
instance?.let { database ->
scope.launch(Dispatchers.IO) {
populateDatabase(database.getDao())
}
}
}
fun populateDatabase(dao: WaterCupDao) {
var word = WaterCupEntity(System.currentTimeMillis(),1,"11.01.2019")
dao.insert(word)
word = WaterCupEntity(System.currentTimeMillis(),2,"11.01.2019")
dao.insert(word)
}
}
}
MyTimeReceiver:
class MyTimeReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action){
Intent.ACTION_TIMEZONE_CHANGED,
Intent.ACTION_DATE_CHANGED,
Intent.ACTION_TIME_CHANGED,
Intent.ACTION_TIME_TICK -> context.sendBroadcast(Intent("refresh_data"))
}
}
}
【问题讨论】:
标签: android android-room android-architecture-components android-broadcastreceiver android-livedata