It’s time to kiss goodbye to your implicit BroadcastReceivers

第一次译文,大家多担待。


Android O 开发者预览版已经发布了!大家可以猜测一下它代表哪一种美味的甜点。


作为Android开发者,现在应该有必要查看一下哪些变化在即将到来的Android O操作系统。文档有很好的划分,因此你可以看到apps适配Android O影响各个API版本的改变在Android O设备上。

你可以跳过Broadcast Limitations部分,因为这就是我即将为你仔细解释的。


摘要: 如果你不打算适配你的app到Android O,你可以不用继续往下看了。但如果你想适配Android O和它带来的新的功能并且你已经注册了隐式广播在你的AndroidManifest文件里,请继续耐心的读下去。

注意:请查看未受到影响广播列表。因此如果你的app注册并响应了例如 ACTION_BOOT_COMPLETED 或者 ACTION_HEADSET_PLUG 等未受影响的广播,它们将照常运作


这都是为了减少手机电量的消耗

最大化提升手机性能与电池续航能力早已是Android的首要任务。在Android Marshmallow,Doze And App Standby 被提出去优化提升手机电池续航能力,一个大多数现代移动手机设备的痛点。

Doze限制所有应用在一个特定窗口去做耗电的后台任务,App Standby 推迟最近很少使用应用的网络活动。随着Doze一起推出的还有JobScheduler,并且Google呼吁开发者使用JobScheduler对所有的后台任务进行安排。


为了节省手机电量,广播作了哪些相应的改变呢?

Android Nougat,移除了三个在AndroidManifest注册的隐式广播的支持。


当适配到Android O的时候,所有隐式广播(除了这些)都将失去作用。


调查显示表明,许多应用注册了很多没有必要的隐式广播在它们的manifest文件里,导致了电池电量的流失。举个例子,许多应用注册了 CONNECTIVITY_ACION 广播Receiver。“然后怎么样呢”,你或许会想,“这会造成对电池电量的消耗?”


想象一下:你有一打监听了网络连接状态改变事件的应用。离开家去商店购物的时候,家里wifi的连接就会断开一旦你离开所住的公寓,Android系统就会发送CONNECTIVITY_ACTION广播,所有监听该事件的应用都会做出相对应的响应


既然wifi不存在了,那手机将会连接数据流量,猜猜会发生什么,CONNECTIVITY_ACTION广播又被再次发送了!同样的事件再次发生当你回到家并连接到家里wifi的时候。


想象一下20个应用监听网络连接状态,拍摄新图片,新应用安装/应用卸载,连接电源/断开电源等等,你很快就会觉得Android开发团队移除AndroidManifest文件里面的隐式广播是明智的。

所有在AndroidManifest文件里面注册了这些隐式广播的应用,都将会被唤醒去接受这些事件,即便它们没有运行在前台甚至没有运行。


我已经注册了广播在Manifest文件里面,要怎么办呢?

不要惊慌。记住,将你已有代码适配到Android O或许是有些挫折,但这并不需要多大的改变,而且这也是为了更好的应用体验嘛。


判断该广播是显示还是隐式

根据官方文档的描述,任何未与你的应用直接关联的广播都是隐式广播。就像文档声明的,ACTION_PACKAGE_REPLACED 是一个隐式广播,既然它会通知你每当一个新安装的应用包。

大部分以前使用的广播都将会是隐式广播的一员。


检查你的应用是否会受到影响

Android开发文档提供了一份未受影响的隐式广播列表,这些广播都将和以前一样照常工作。这代表如果你的应用仅仅在AndroidManifest文件里面注册了这些广播,记住,是只有列表这些,那么你就不会受到影响。

最常用的未受到影响的几个应该是 ACTION_BOOT_COMPLETED,ACTION_HEADSET_PLUG 和 蓝牙状态改变的ACTION_CONNECTION_STATE_CHANGED 等等。


JobScheduler使用

如果你监听了网络连接,充电,手机闲置事件,那你应该使用JobScheduler来代替。


ComponentName myService = new ComponentName(this, MyService.class);
JobInfo myJob = new JobInfo.Builder(myService)
        .setRequiresCharging(true)
        .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
        .setPersisted(true)
        .build();

JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(myJob);

JobScheduler跟Android系统和Doze电池优化能很好的协调运行。它提供了在自定义条件下执行任务的功能。举个例子,你可以安排一个任务在空闲状态的设备连接进行充电并且有一个能使用的网络连接的时候执行。

JobScheduler只在Android Lollipop(API 21)及以上版本支持。如果应用minSdkVersion低于21,可以使用一些三方库提供向后的兼容,官方推荐 FirebaseJobDispatcher

Context.registerReceiver()照常工作
不管你的广播是隐式还是显示,你始终可以在Activity,Service,Fragment或者一个自定义View内使用 Context.registerReceiver()方法注册它。

因此,如果你的应用有一个Receiver监听充电事件:

...
<receiver android:name=".ChargerReceiver">
    <intent-filter>
        <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
    </intent-filter>
</receiver>
...


你应该将其从AndroidManifest文件移除,将监听逻辑移动到你的Activity,Service,Fragment:


...
public class MainActivity extends AppCompatActivity {
    private BroadcastReceiver chargerReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        chargerReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // TODO: Awesome things
            }
        };

        registerReceiver(
                chargerReceiver,
                new IntentFilter(Intent.ACTION_POWER_CONNECTED)
        );
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(chargerReceiver);
    }
}
...

这个与Context.registerReceiver不同的就是你最终必须对其取消注册,虽然receiver定义在manifest里面的不管怎么都将会唤醒你的应用。什么时候取消注册就看你第一次注册receiver的地方。

如果在Activity/Fragment里面注册的receiver,一个好的取消注册地方就是onDestroy回调里面。当注册在Service里面,当你不需要接受这些事件的时候取消注册。

总结
移除所有AndroidManifest文件里的隐式广播(除了 这些),使用JobScheduler, FirebaseJobDispatcher或其他替代方式。如果这些都不支持你监听的事件,根据需求注册BroadcastReceivers在Activity, Service, Fragment 或者 View 里。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值