基本概念
Android应用程序可以发送或接收来自Android系统和其他Android应用程序的广播消息,类似于发布-订阅设计模式。应用程序中可以注册广播,以接收特定广播。(可参考andorid官网的描述)
android广播涉及两个重要的角色:广播发送者(broadcast sender)、广播接收者(broadcast receiver) 广播原理/生命周期/分类
broadcast receiver的两种注册方式
1.动态注册:在java代码中注册
动态注册不是常驻型广播,也就是说广播的存与亡跟随程序的生命周期
两个核心方法:
//注册
registerReceiver(myReceiver1,intentFilter);
//取消注册(当动态注册时,不要忘了取消注册,为了尽可能避免内存泄漏问题)
unregisterReceiver(myReceiver1);
2.静态注册:在manifest文件中注册
静态注册是常驻型广播,即使应用程序关闭后,broadcast receiver仍处于活动状态,可以正常接收发来的广播。
弊端:broadcast receiver始终处于活动状态,比较耗费cpu和电源等资源
例如:
<receiver android:name=".MyReceiver1">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
android 8.0及更高版本不支持大多数的静态注册broadcast receiver,官网说明
动态注册的一个例子——接收 网络状态改变的系统广播
MyReceiver1
package com.clc.app6;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.nfc.Tag;
import android.util.Log;
import android.widget.Toast;
public class MyReceiver1 extends BroadcastReceiver {
public static final String TAG = "MyReceiver1";
@Override
public void onReceive(Context context, Intent intent) {
/*
注意:
如果需要在onReceiver完成一些耗时操作,应该考虑在Service中开启一个新线程处理耗时操作,
不要在BroadcastReceiver中开启一个新的线程,因为BroadcastReceiver生命周期很短,在执行完onReceiver以后就结束,
如果开启一个新的线程,可能出现BroadcastRecevier退出以后线程还在,而如果BroadcastReceiver所在的进程结束了,
该线程就会被标记为一个空线程,根据Android的内存管理策略,在系统内存紧张的时候,会按照优先级,结束优先级低的线程,而
空线程无异是优先级最低的,这样就可能导致BroadcastReceiver启动的子线程不能执行完成。
*/
Toast.makeText(context, TAG+" start",Toast.LENGTH_LONG);
}
}
动态注册
package com.clc.app6;
import androidx.appcompat.app.AppCompatActivity;
import android.content.IntentFilter;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
MyReceiver1 myReceiver1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 动态注册BroadcastReceiver
* 这种情况,不用在AndroidManifest.xml文件中注册
*/
myReceiver1 = new MyReceiver1();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(myReceiver1,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
/**
* 取消注册
*/
unregisterReceiver(myReceiver1);
}
}
发送广播的一个例子
broadcast receiver
package com.clc.app8;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class Receiver1 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"dynamic",Toast.LENGTH_SHORT).show();
}
}
动态注册和发送广播
package com.clc.app8;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
Receiver1 receiver1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* dynamic register
*/
receiver1 = new Receiver1();
IntentFilter intentFilter = new IntentFilter();
//这里的action和广播发送处的action是对应的
intentFilter.addAction("dynamic");
registerReceiver(receiver1,intentFilter);
findViewById(R.id.btn_dynamic).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setAction("dynamic");
//广播发送的载体是intent对象,intent的action代表广播的内容
sendBroadcast(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver1);
}
}