Service
跑步 vs 不Service
跑步
每个应用程序至少有一个Process
在您的应用程序运行时启动。该过程至少使用一些内存,人们喜欢使用任务杀手来释放它,尽管 Android 会在实际需要内存时自动执行此操作。这种内存对于Service
本案来说绝对是一个劣势。
CPU / 电池使用量仅在发生某些事情并因此主动使用 CPU 或当您的应用程序强制系统保持资源启用时(例如,当您保持WakeLock
. 如果您不执行任何此操作,您的应用程序使用大约 0 CPU / 电池,并且其行为就像一个停止的应用程序,它保存在内存中以加快重新启动它的速度。如果您的代码正在运行,那么您无意中使用某些资源的可能性肯定会更高。
如果根本没有Service
/Activity
正在运行,并且您只需BroadcastReceiver
在清单中注册 a ,您基本上就是告诉系统将您的接收器包含在它在发送广播时检查的接收器列表中。非常少的额外工作。
清单接收器还具有在内存压力很高时系统不会被杀死的优点。那些接收器只是工作,你根本不需要关心。如果您愿意,您甚至可以启用/禁用它们。
ContentObserver
对比BroadcastReceiver
两者都应该使用ActivityThread
//通常称为“UI 线程”的机制,它将所有事件传递到您的应用程序并调用所有Looper
, etc方法。当这些方法出现问题时,当您查看堆栈跟踪时很容易看到:MessageQueue
onCreate
onTouch
AndroidRuntime(521): FATAL EXCEPTION: main
AndroidRuntime(521): java.lang.RuntimeException: MotionEvent{405215b0 action=0 x=66.0 y=78.0 pressure=1.0 size=0.0} recycled twice!
AndroidRuntime(521): at android.view.MotionEvent.recycle(MotionEvent.java:659)
AndroidRuntime(521): at android.view.ViewRoot.handleMessage(ViewRoot.java:1880)
AndroidRuntime(521): at android.os.Handler.dispatchMessage(Handler.java:99)
AndroidRuntime(521): at android.os.Looper.loop(Looper.java:123)
AndroidRuntime(521): at android.app.ActivityThread.main(ActivityThread.java:3647)
如果不发送广播或内容更改通知,则该线程只是等待。等待不使用 CPU(即一直在循环中主动循环),但告诉系统它不需要为该线程安排处理时间。那时 CPU 使用率实际上约为 0。因此,IMO 在运行时注册两者之一完全没有区别。
唯一可以为其中一种方法带来优势的区别是,如果这些方法更频繁地触发。
其中1对5
不要紧。系统中有如此多的接收者/观察者,添加 1 或 5 并不重要。如果添加 1000,您可能会注意到
附带说明:不要阻止 UI 线程完成它的工作。尽管接收器和服务没有 UI,但它们的回调方法在 UI 线程上执行。因此,如果您执行任何长时间运行的操作,例如在任何onReceive
/ Service#onCreate
etc 方法中下载内容,这将导致ANR,就像在Activity#onCreate
.