实现一个强制下线的功能。
先来分析一下问题,强制下线其实就是收到一条广播,然后将所有的Activity关闭,跳回到登录界面。就是这么简单。
然后细分一下需要哪些东西
想要将所有的Activity关闭,那我们就得管理一下所有的Activity,创建一个Activity数组,在这个类中添加、删除活动
还得让每个Activity在创建时就添加到上述数组中去,那就来个baseActivity,让所有的Activity都继承它。在该类中实现添加到数组的方法
剩下的就是收到一个广播,然后关闭Activity回到登录界面,就是上篇的内容了。很简单啦。来看下面具体的代码
照例先写一下要做的事:
1.来一个管理Activity数组的类,在其中实现addActivity() removeActivity() finishAll()这三个方法。
2.写一个BaseActivity,让所有的Activity都继承它。它的目的就是在create和destroy时从数组中添加/删除该Activity
看代码吧
1.ActivityCollector类
public class ActivityCollector {
public static List<Activity> activitys = new ArrayList<Activity>();
public static void addActivity(Activity activity){
activitys.add(activity);
}
public static void removeActivity(Activity activity){
activitys.remove(activity);
}
public static void finishAll(){
for (Activity activity : activitys){
if (!activity.isFinishing()){
activity.finish();
}
}
}
public static List<Activity> activitys = new ArrayList<Activity>();
public static void addActivity(Activity activity){
activitys.add(activity);
}
public static void removeActivity(Activity activity){
activitys.remove(activity);
}
public static void finishAll(){
for (Activity activity : activitys){
if (!activity.isFinishing()){
activity.finish();
}
}
}
}
2.BaseActivity类,让别的Activity继承它就好了,逻辑清晰
public class BaseActivity
extends Activity {
@Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
ActivityCollector. addActivity( this);
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector. removeActivity( this);
}
@Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
ActivityCollector. addActivity( this);
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector. removeActivity( this);
}
}
然后写一个Activity,算是模拟一个应用中众多Activity中的一个。就写一个功能,点击按钮发出下线通知。用广播接收器来做关闭所有Activity的操作,将它们的功能分开。广播接收器就做收到广播后的动作就好。
还是先写一下要做的:
1.写一个登录的界面,登录确认后用intent跳到别的Activity,用B来代替
2.在B中写个按钮,发布下线通知(就是发一条广播)PS:记得B要继承BaseActivity类哦
3.写好广播接收器,收到通知后清空Activity,调回登录界面。
好了,开始看代码吧,布局这些就不再写了。没什么意思
1.LoginActivity类,记得继承BaseActivity类哦
public class LoginActivity
extends BaseActivity {
private EditText et_account;
private EditText et_password;
private Button btn_login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. login);
et_account = (EditText) findViewById(R.id. account);
et_password = (EditText) findViewById(R.id. password);
btn_login = (Button) findViewById(R.id. login);
btn_login.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
String account = et_account.getText().toString();
String password = et_password.getText().toString();
//如果账号是admin,密码是123456.就登录进去
if (account.equals( "admin") && password.equals( "123456")){
Intent intent = new Intent(LoginActivity. this,MainActivity. class);
startActivity(intent);
finish();
} else {
Toast. makeText(LoginActivity. this, "账户密码错误",Toast. LENGTH_LONG).show();
}
}
});
}
private EditText et_account;
private EditText et_password;
private Button btn_login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. login);
et_account = (EditText) findViewById(R.id. account);
et_password = (EditText) findViewById(R.id. password);
btn_login = (Button) findViewById(R.id. login);
btn_login.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
String account = et_account.getText().toString();
String password = et_password.getText().toString();
//如果账号是admin,密码是123456.就登录进去
if (account.equals( "admin") && password.equals( "123456")){
Intent intent = new Intent(LoginActivity. this,MainActivity. class);
startActivity(intent);
finish();
} else {
Toast. makeText(LoginActivity. this, "账户密码错误",Toast. LENGTH_LONG).show();
}
}
});
}
}
2,在MainActivity中写个按钮,这里就是把main当成一个简单的Activity了,理解就好
public class MainActivity
extends BaseActivity {
private Button forceOffline;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_main);
forceOffline = (Button) findViewById(R.id. force_offline);
forceOffline.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent( "com.example.broadcastbestpractice.FORCE_OFFLINE");
sendBroadcast(intent);
}
});
}
private Button forceOffline;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_main);
forceOffline = (Button) findViewById(R.id. force_offline);
forceOffline.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent( "com.example.broadcastbestpractice.FORCE_OFFLINE");
sendBroadcast(intent);
}
});
}
}
//注意看广播的信息,一会咱在注册广播的时候要用到的。
3.广播接收器中要收到广播后清空Activity,跳回登录面。牢记接收器的步骤,实现onReceiver,注册Receiver,用到的权限也需要注册
public class ForceOfflineReceiver
extends BroadcastReceiver {
@Override
public void onReceive( final Context context, Intent intent) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle( "Warning...")
.setMessage( "You are forced to be offline. Please try to login again.")
.setCancelable( false)
.setPositiveButton( "OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCollector. finishAll(); //销毁所有的活动
Intent intent = new Intent( context,LoginActivity. class);
intent.addFlags(Intent. FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent); //重启LoginActivity
}
});
AlertDialog alertDialog = dialogBuilder.create();
//设置AlertDialog的类型,保证在广播接收器中能正常弹出
alertDialog.getWindow().setType(WindowManager.LayoutParams. TYPE_SYSTEM_ALERT);
alertDialog.show();
}
@Override
public void onReceive( final Context context, Intent intent) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle( "Warning...")
.setMessage( "You are forced to be offline. Please try to login again.")
.setCancelable( false)
.setPositiveButton( "OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCollector. finishAll(); //销毁所有的活动
Intent intent = new Intent( context,LoginActivity. class);
intent.addFlags(Intent. FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent); //重启LoginActivity
}
});
AlertDialog alertDialog = dialogBuilder.create();
//设置AlertDialog的类型,保证在广播接收器中能正常弹出
alertDialog.getWindow().setType(WindowManager.LayoutParams. TYPE_SYSTEM_ALERT);
alertDialog.show();
}
}
还得看一下配置文件中的注册信息。
AndroidManifest.xml
<?
xml version=
"1.0"
encoding=
"utf-8"
?>
< manifest xmlns: android = "http://schemas.android.com/apk/res/android"
package= "com.example.yawen_li.broadcastbestpractice" >
< manifest xmlns: android = "http://schemas.android.com/apk/res/android"
package= "com.example.yawen_li.broadcastbestpractice" >
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>//这是让弹出的对话框置于顶层
<
application
android :allowBackup= "true"
android :icon= "@mipmap/ic_launcher"
android :label= "@string/app_name"
android :supportsRtl= "true"
android :theme= "@style/AppTheme" >
< activity android :name= ".MainActivity" >
< intent-filter>
< action android :name= "android.intent.action.MAIN" />
< category android :name= "android.intent.category.LAUNCHER" />
</ intent-filter>
</ activity>
< activity
android :name= ".LoginActivity"
android :label= "@string/title_activity_login"
android :parentActivityName= ".BaseActivity">
< meta-data
android :name= "android.support.PARENT_ACTIVITY"
android :value= "com.example.yawen_li.broadcastbestpractice.BaseActivity" />
android :allowBackup= "true"
android :icon= "@mipmap/ic_launcher"
android :label= "@string/app_name"
android :supportsRtl= "true"
android :theme= "@style/AppTheme" >
< activity android :name= ".MainActivity" >
< intent-filter>
< action android :name= "android.intent.action.MAIN" />
< category android :name= "android.intent.category.LAUNCHER" />
</ intent-filter>
</ activity>
< activity
android :name= ".LoginActivity"
android :label= "@string/title_activity_login"
android :parentActivityName= ".BaseActivity">
< meta-data
android :name= "android.support.PARENT_ACTIVITY"
android :value= "com.example.yawen_li.broadcastbestpractice.BaseActivity" />
</activity>
//注册好接收器
<
receiver
android
:name=
".ForceOfflineReceiver">
< intent-filter>
< action android :name= "com.example.broadcastbestpractice.FORCE_OFFLINE"/>
</ intent-filter>
</ receiver>
</ application>
</ manifest>
< intent-filter>
< action android :name= "com.example.broadcastbestpractice.FORCE_OFFLINE"/>
</ intent-filter>
</ receiver>
</ application>
</ manifest>
就这样,没咯~
是不是很简单呢。这其中还涉及到一点关于intent flags以及Task的相关属性。在文中也没有介绍到,可以参见网上的一些博文,这里提供一个连接供大家学习:
http://www.cnblogs.com/lwbqqyumidi/p/3775479.html
好啦~就这样吧。晚安咯