Closed AkshayChordiya closed 7 years ago
The ViewModel should be used closely with an Activity or a Fragment, so it's destined to live in the UI layer of your application. Therefore, I don't recommend using the ViewModel in a Service. Create a different class, that would be used in the Service and, if needed, in the ViewModel. Like this you ensure the separation of concerns and avoid giving the ViewModel more responsibilities than needed.
My service has a UI, which it displays all the time. I using ViewModel be still wrong? Can you elaborate more on this? @florina-muntenescu
How your Service negotiate with the UI?
@MotiBartov it's a https://github.com/google/hover floating tabs
How your Service negotiate with the UI?
Control RemoteViews
class FCMessagingService : FirebaseMessagingService(), LifecycleOwner {
private var fcmTokenUpload: Boolean by Preference(Constant.FCM_TOKEN_UPLOAD, false)
private var customerId: String by Preference(Constant.CUSTOMER_ID, "")
private lateinit var mViewModel: UserViewModel
private val mDispatcher = ServiceLifecycleDispatcher(this)
override fun getLifecycle() = mDispatcher.lifecycle
override fun onCreate() {
mDispatcher.onServicePreSuperOnCreate()
mViewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(UserViewModel::class.java)
mViewModel.let(lifecycle::addObserver)
mViewModel.apply {
mFcmTokenUpload.observe(this@FCMessagingService, Observer {
fcmTokenUpload = it
})
}
super.onCreate()
}
override fun onStart(intent: Intent?, startId: Int) {
mDispatcher.onServicePreSuperOnStart()
super.onStart(intent, startId)
}
override fun onDestroy() {
mDispatcher.onServicePreSuperOnDestroy()
lifecycle.removeObserver(mViewModel)
super.onDestroy()
}
/**
* Called when message is received.
*/
override fun onMessageReceived(remoteMessage: RemoteMessage) {
var msg = Messaging("", "", "", "0")
//消息
if (remoteMessage.data.isNotEmpty()) {
remoteMessage.data.forEach {
if (it.key == "data") { // "data": "{\"id\":\"2611620\",\"type\":\"2\"}"
try {
msg = Gson().fromJson(it.value, Messaging::class.java)
} catch (e: JsonSyntaxException) {
e.printStackTrace()
}
}
}
}
//通知
remoteMessage.notification?.let {
sendNotification(it.title, it.body, msg)
}
}
//新token 发送给app的服务器,用于定向发送推送消息。
override fun onNewToken(token: String) {
mViewModel.setRegId(customerId, token)
}
}
Can't use this - "mFcmTokenUpload.observe(this@FCMessagingService, Observer " because for observer, we need main thread to run. And FCM runs on worker thread.
The ViewModel should be used closely with an Activity or a Fragment, so it's destined to live in the UI layer of your application. Therefore, I don't recommend using the ViewModel in a Service. Create a different class, that would be used in the Service and, if needed, in the ViewModel. Like this you ensure the separation of concerns and avoid giving the ViewModel more responsibilities than needed.
@florina-muntenescu What about the Screen class of Android Auto Navigation/ Parking apps? How can we use ViewModel there? Your thoughts?
@florina-muntenescu What about the Screen class of Android Auto Navigation/ Parking apps? How can we use ViewModel there? Your thoughts?
Same thing.
@florina-muntenescu What about the Screen class of Android Auto Navigation/ Parking apps? How can we use ViewModel there? Your thoughts?
Same thing.
Actually I realised that we don't need a View Model (from Android) for that case. Why did we used a ViewModel class from Android? Because it handled the Configuration changed automatically and can be shared within multiple fragments hosted on the same activity.
But that's not the case with Screen classes. They don't go through configuration changes. They do not host any sub view/ fragment that needs it to share the data. And hence it's not required for this case.
However to separate the presentation logic, if you want, you can Use an Android's provided View Model out of the box.
Like this
viewModel = ViewModelProvider(ViewModelStore(), viewModelFactory).get(HomeViewModel::class.java)
This is just to make sure that if you are re-using a View Model for both Screen and a Fragment/Activity. Else or you could just create your own class, name it to ViewModel. Initialise it on create method of the screen.
Hi,
Everything is great with
ViewModel
. They work as expected in theActivity
andFragment
. Recently I have encountered an need to use theViewModel
inService
. I'm not sure how exactly to do that.I found one answer on StackOverFlow: https://stackoverflow.com/questions/44708202/observe-livedata-from-foreground-service But I want to know what's the best practice to use
ViewModel
inService
.