ContentObserver vs. BroadCastReceiver : Battery Us

2019-05-04 11:26发布

问题:

Since there is such a needed concern for an application's battery usage, ram and cpu usage, what is the expense of multiple contentobservers vs. multiple broadcastreceivers?

Example 1:

A service running with START_STICKY using 5 contentobservers registered/unregistered properly.

Example 2:

A service being fired from 5 broadcastreceivers set in the manifest.

Example 3:

A service running with START_STICKY using 5 registered broadcastreceivers.

What is the true difference in battery usage/ram/cpu between an observer and a receiver? Can any pros chime in on this? I'm assuming 1 instance wouldn't make much of a difference, but lets take the above examples with 5 running at once.

回答1:

Service running vs no Service running

Each app has at least one Process that is started when your app is running. That process uses at least some memory and people like to use task killers to free that although Android does that automatically once memory is actually required. This memory is definitely a disadvantage for the Service case.

CPU / battery usage is only increased when something is happening and therefore actively using the CPU or when your app forces the system to keep resources enabled e.g. when you keep a WakeLock. If you don't do any of this your app uses about 0 CPU / battery and acts pretty much like a stopped app that is kept in memory to speed up restarting it. The probability that you inadvertently use some resources is certainly higher if your code is running.

If no Service / Activity is running at all and you just register a BroadcastReceiver in your manifest you basically tell the system to include your receiver in the list of receivers it checks when sending broadcasts. Very minimal extra work.

Manifest receivers also have the advantage that the system can't get killed when the memory pressure is high. Those receivers just work and you don't need to care at all. You can even enable / disable them if you wish to do so.

ContentObserver vs BroadcastReceiver

Both should use the ActivityThread / Looper / MessageQueue mechanism usually refered to as the "UI Thread" which delivers all events to your app and calls all the onCreate, onTouch etc methods. Easily visible when you look at a stacktrace when something breaks in these methods:

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)

If no broadcast or content change notification is to be delivered that thread simply waits. Waiting does not use the CPU (i.e. actively cycle in a loop all the time) but tells the system that it does not need to schedule processing time for that thread. CPU usage is effectively ~0 in that time. So IMO there is no difference at all between registering one of the two at runtime.

The only difference that could give advantages to one of the methods would be if one if the methods trigger more often.

1 vs 5 of them

Does not matter. There are so many receivers / observers in the system that it does not really matter if you add 1 or 5. If you add like 1000 you'll probably notice

On a sidenote: Don't block the UI thread from doing it's work. Although receivers and services don't have UI their callback methods are executed on the UI thread. So if you do any long-running operation like downloading stuff in any of the onReceive / Service#onCreate etc methods that will lead to ANRs the same way it does e.g. in Activity#onCreate.