4

由于对应用程序的电池使用、内存和 cpu 使用有如此必要的关注,那么多个 contentobservers 与多个广播接收器的开销是多少?

示例 1:

使用 START_STICKY 运行的服务,使用 5 个正确注册/取消注册的内容观察器。

示例 2:

从清单中设置的 5 个广播接收器触发的服务。

示例 3:

使用 5 个注册广播接收器以 START_STICKY 运行的服务。

观察者和接收者之间的电池使用量/内存/cpu 的真正区别是什么?任何专业人士都可以对此发表意见吗?我假设 1 个实例不会有太大的不同,但让我们以上面的示例为例,同时运行 5 个。

4

1 回答 1

8

Service跑步 vs 不Service跑步

每个应用程序至少有一个Process在您的应用程序运行时启动。该过程至少使用一些内存,人们喜欢使用任务杀手来释放它,尽管 Android 会在实际需要内存时自动执行此操作。这种内存对于Service本案来说绝对是一个劣势。

CPU / 电池使用量仅在发生某些事情并因此主动使用 CPU 或当您的应用程序强制系统保持资源启用时(例如,当您保持WakeLock. 如果您不执行任何此操作,您的应用程序使用大约 0 CPU / 电池,并且其行为就像一个停止的应用程序,它保存在内存中以加快重新启动它的速度。如果您的代码正在运行,那么您无意中使用某些资源的可能性肯定会更高。

如果根本没有Service/Activity正在运行,并且您只需BroadcastReceiver在清单中注册 a ,您基本上就是告诉系统将您的接收器包含在它在发送广播时检查的接收器列表中。非常少的额外工作。

清单接收器还具有在内存压力很高时系统不会被杀死的优点。那些接收器只是工作,你根本不需要关心。如果您愿意,您甚至可以启用/禁用它们。

ContentObserver对比BroadcastReceiver

两者都应该使用ActivityThread//通常称为“UI 线程”的机制,它将所有事件传递到您的应用程序并调用所有Looper, etc方法。当这些方法出现问题时,当您查看堆栈跟踪时很容易看到:MessageQueueonCreateonTouch

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#onCreateetc 方法中下载内容,这将导致ANR,就像在Activity#onCreate.

于 2012-09-07T12:58:47.160 回答