是否可以在服务中引用上下文,但不能使用应用程序上下文?
当发生某些事情时,我正试图实现从服务中显示snackbar的能力。这应该在MULTIPLE活动中完成。要做到这一点,我需要上下文,然后从中引用以使用此行获取视图:
View rootView = ((Activity)context).getWindow().getDecorView().findViewById(android.R.id.content)
我在服务中这样做:
class MyService : Service() {
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
//TODO do something useful
val view: View = (this.applicationContext as Activity).window.decorView.findViewById(android.R.id.content)
Timber.d("some jobe done")
return Service.START_NOT_STICKY
}
override fun onBind(intent: Intent): IBinder? {
//TODO for communication return IBinder implementation
return null
}
}
但是,在引用应用程序上下文时,我会收到错误,并将其强制转换为Activty:
Caused by: java.lang.ClassCastException: com.myapp.Application cannot be cast to android.app.Activity
是否可以正确处理(参考我的用例)?
我正在努力实现在发生某些事情时从服务中显示snackbar的能力。
这不是一个好主意。例如,它没有解决您没有正在运行的活动的情况。
要做到这一点,我需要上下文,然后从中引用以使用此行获取视图:
不,你需要Activity
对象,正如你的演员看到的那样。
是否可以正确处理(参考我的用例)?
不是你正在接近问题的方式。
您的情况是:服务检测到某个事件,并且服务希望让用户知道该事件。有两种可能性:
解决此问题的典型方法是使用某种形式的事件总线(LocalBroadcastManager
,greenrobot的EventBus或任意数量的基于RxJava的事件总线实现):
onStart()
/ onStop()
)这种方法可以更好地分离关注点,因为服务不应该关心UI如何让用户了解事件。它还可以干净地处理您没有可用于小吃店的活动的情况。
This sample app用greenrobot的EventBus演示了这种方法,而this sample app用LocalBroadcastManager
演示了这种方法。
还有其他解决方案不涉及真正的事件总线,例如服务更新存储库,它通过反应方式更新UI组件(例如,RxJava导致LiveData
)。但是,服务不应该试图直接操纵活动的UI,部分原因可能是没有活动。