building_battery-conscious_apps
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| building_battery-conscious_apps [2018/11/01 12:49] – [A review of broadcast receivers] kalaschnikow | building_battery-conscious_apps [2020/11/11 08:47] (current) – [Intent to the settings, where you can move your app to the whitelist] kalaschnikow | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Building Battery-Conscious Apps ====== | ||
| + | |||
| + | Das ist mein Konspekt von dem Online-Kurs [[https:// | ||
| + | |||
| + | ===== Introduction ===== | ||
| + | |||
| + | ==== Why be battery conscious? ==== | ||
| + | ... | ||
| + | |||
| + | ===== 1. Basics of Battery Usage ===== | ||
| + | |||
| + | ==== Principles of battery-concious apps ==== | ||
| + | |||
| + | https:// | ||
| + | |||
| + | Wake-Up has costs: | ||
| + | * CPU on | ||
| + | * Screen on | ||
| + | * Data (Wi-Fi or cellular) on | ||
| + | |||
| + | Official documentation: | ||
| + | |||
| + | Smart Design (aka Lazy First design) | ||
| + | - Reduce (e.g. resolution of photos for upload/ | ||
| + | - Defer | ||
| + | - Coalesce (combining transactions to a " | ||
| + | - Rethink | ||
| + | | ||
| + | |||
| + | ===== 2. Battery Drain and Workarounds ===== | ||
| + | |||
| + | |||
| + | ==== Considerations for using AlarmManager ==== | ||
| + | https:// | ||
| + | |||
| + | * Schedule asynchronous operations | ||
| + | * Time-based | ||
| + | * Single or repetitive | ||
| + | * Perfect for exact time-based scheduling | ||
| + | * Periodic background tasks | ||
| + | * Combined effects cause battery drain | ||
| + | * Wake up has a cost | ||
| + | |||
| + | ==== Pitfalls of poor AlarmManager usage ==== | ||
| + | https:// | ||
| + | |||
| + | - Background network operations (AlarmManager does not have intelligent dispatch logic) | ||
| + | - Alarms does not survive reboots (Extra logic required, e.g. BroadcastReceiver) | ||
| + | - Exact Alarm may not be exact | ||
| + | * Since Kitkat | ||
| + | * setExactAndAllowWhileIdle -> is affected by Doze Mode | ||
| + | - Doze Mode introduces complexity (e.g. '' | ||
| + | | ||
| + | Takeaways: | ||
| + | * Avoid network operations | ||
| + | * Doze Mode affects AlarmManager | ||
| + | * Maybe better would be to switch to JobScheduler (because it is not time driven, but event driven) | ||
| + | | ||
| + | ==== Considerations for using background-started services ==== | ||
| + | https:// | ||
| + | * Background Started Services | ||
| + | * typically long running operations with no UI (e.g. music player) | ||
| + | * started via an API call | ||
| + | * contract: | ||
| + | * client calls **Context.startService()** | ||
| + | * system calls **Service.onStartCommand()** | ||
| + | * Service stops | ||
| + | * service stops itself with **Service.stopSelf()** | ||
| + | * OR: | ||
| + | * client calls **Service.stopService()** | ||
| + | * System requires service to remain running until stopped explicitly | ||
| + | * Note: in production **IntentService** would be better as simple **Service** | ||
| + | * When to Use Background Started Service | ||
| + | * intense, low-priority tasks not noticed by user | ||
| + | * irregular, user-driven background tasks | ||
| + | * stateless reentrant operations (e.g. refreshing news content) | ||
| + | * work queue processor pattern (IntentService) | ||
| + | * Note: if task is periodic scheduled job may be a better choice | ||
| + | ==== Pitfalls of poor background-started service usage ==== | ||
| + | https:// | ||
| + | |||
| + | * Pitfall 1: Android | ||
| + | * Google is tightening restrictions | ||
| + | * Pitfall 2: No Rules or Policy Support | ||
| + | * Connectivity checks | ||
| + | * Active connection | ||
| + | * Airplane mode | ||
| + | * Remote server availability | ||
| + | * Appropriateness checks | ||
| + | * Battery level | ||
| + | * Roaming status | ||
| + | * Metered connection | ||
| + | * Back off and retry policy | ||
| + | * Retry when? | ||
| + | * Retry how often? | ||
| + | * Pitfall 3: No intelligent batching | ||
| + | * No batching unlike AlarmManager | ||
| + | * Cannot differentiate between services and different apps | ||
| + | * Pitfall 4: Other reasons | ||
| + | * Idle processes are wasteful | ||
| + | * Fragmentation is a problem | ||
| + | |||
| + | * Takeaway | ||
| + | * Use job scheduler for most cases | ||
| + | * Use started services for simple one-shot background tasks | ||
| + | |||
| + | ==== A review of broadcast receivers ==== | ||
| + | https:// | ||
| + | * Introduction to Broadcast Receivers | ||
| + | * support event-driven programming | ||
| + | * used for many system events | ||
| + | * Interprocess communication (IPC) | ||
| + | * delivered via Intent | ||
| + | * Intents specify actions and optional extras | ||
| + | * should extend **BroadcastReceiver** | ||
| + | * should implement **onReceive()** | ||
| + | |||
| + | ==== Registering a broadcast receiver ==== | ||
| + | https:// | ||
| + | * Statically registered (AndroidManifest.xml) | ||
| + | * Dynamically registered (through the Java code) | ||
| + | |||
| + | ==== Triggering a broadcast receiver ==== | ||
| + | |||
| + | https:// | ||
| + | |||
| + | Two posibilities to trigger a broadcast receiver: | ||
| + | - Call implicit trigger | ||
| + | * Candidates matched via filter | ||
| + | * Recipients unknown until match | ||
| + | * Recipients may change | ||
| + | - Explicit trigger | ||
| + | * Invocation via code | ||
| + | * Recipients known | ||
| + | * Recipients never change | ||
| + | | ||
| + | * Any app can define its own intent | ||
| + | |||
| + | Example of triggering explicitly: | ||
| + | <code java> | ||
| + | Intent i = new Intent(" | ||
| + | .setComponent(new ComponentName(context.getPackageName(), | ||
| + | context.setBroadcast(i); | ||
| + | </ | ||
| + | |||
| + | ==== Considerations of static implicit broadcast receivers ==== | ||
| + | https:// | ||
| + | |||
| + | ===== Post Scriptum ===== | ||
| + | |||
| + | This post scriptum is not based on the online course, but on other articles. | ||
| + | |||
| + | ==== Intent to the settings, where you can move your app to the whitelist ==== | ||
| + | From [[https:// | ||
| + | <code java> | ||
| + | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | ||
| + | Intent intent = new Intent(); | ||
| + | String packageName = getPackageName(); | ||
| + | PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); | ||
| + | if (!pm.isIgnoringBatteryOptimizations(packageName)) { | ||
| + | intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); | ||
| + | intent.setData(Uri.parse(" | ||
| + | startActivity(intent); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
