《第一行代码》阅读笔记(十九)——广播的最佳实践(强制下线功能)
这里笔者就不重复书籍上面的话了,作者的表达十分凝练和清晰,主要说下笔者自己的感悟。学习到这里的时候笔者认为广播的存在就是打破显式intent传播的局限性,显式intent只能Activity之间互相传递,肯定是不满足我们的需求的。如果想要系统和APP,或者一个APP和另一个APP,甚至一个APP中不是简单的跳转关系都可以使用广播。例如本例中,强制下线这个功能不是某一个Activity和LoginActivity之间的传递,而是任何一个Activity触发这个功能都需要跳转到LoginActivity,我们当然不能给每个Activity写个actionStart,所以我们就提前设置好接收广播后的操作,就是跳转到LoginActivity,在需要的时候发送这条广播。其实不难发现广播和intent之间联系紧密。废话不多说,让我们来看看这个项目吧。
这里笔者是看了一遍书,然后自己敲的,遇到不会的再去看看书。所以和书籍上面有的命名不太一致,其实也比较推荐大家使用这种方法,而不是盲目的对着敲。
第一步:回顾
因为需要退出所有程序,所以大家一起回顾下第二章活动最佳实践的BaseActivity和ActivityCollection。这里就不废话了
第二步:登录界面
画个这样的页面,书上说是自动生成,还是别了,因为现在的AS和书上的版本已经差挺多的了,生成出来一大堆没有用的。
第三步:修改LoginActivity
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = accountEdit.getText().toString();
String password = passwordEdit.getText().toString();
if (username.equals("admin") && password.equals("123456")) {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
}else {
Toast.makeText(LoginActivity.this, "账号密码错误!", Toast.LENGTH_SHORT).show();
}
}
});
其他的不说了,点击登录按钮后,首先获取EditText的内容,然后赋值给username和password。之后就是一个判断,如果用户名是admin并且密码是123456的话,跳转到主页面,如果不是弹出一个Toast。
第四步:编辑主页面和修改MainActivity
public class MainActivity extends BaseActivity {
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.firstcode.broadcasttestpractice.FORCE_OFFLINE");
sendBroadcast(intent);
}
});
}
}
很简单,就是点击发送一个广播。
第五步:接收广播
既然发出来,就一定要接收,怎么接收呢?在BaseActivity中添加下面的代码
private offlineBroadcastReceiver receiver;
...
@Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.firstcode.broadcasttestpractice.FORCE_OFFLINE");
receiver = new offlineBroadcastReceiver();
registerReceiver(receiver, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
if (receiver != null) {
unregisterReceiver(receiver);
receiver = null;
}
}
...
class offlineBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Warning");
builder.setMessage("You are forced to be offline. Please try to login again");
builder.setCancelable(false);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCollection.finishAll();
Intent intent1 = new Intent(context, LoginActivity.class);
context.startActivity(intent1);
}
});
builder.show();
}
}
和之前的动态注册都是差不多的,首先声明一个内部类,重写onReceive方法,该方法内就是接收到广播后的操作。本案例中是弹出了一个AlertDialog对话框。并且设置不能取消,同时添加一个按钮,这个按钮的功能就是关闭所有Activity,然后再跳转回LoginActivity。然后在Activity的声明周期中的resume注册这个接收器,在pause的时候取消注册。