Android综合例子——强制下线

  • 为方便管理所有活动,创建ActivityCollector类

//activity管理器
public class ActivityCollector {
    public static List<Activity> activities = new ArrayList<>();
    public static void addActivity(Activity activity){
        activities.add(activity);
    }
    public static void removeActivity(Activity activity){
        activities.remove(activity);
    }
    public static void finishAll(){
        for (Activity activity : activities){
            if(!activity.isFinishing()){
                activity.finish();
            }
        }activities.clear();
    }
}
  • 创建BaseActiviy作为所有类的父类。

(1)注册广播
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.broadcastbestpractice.FORCE_OFFLINE");//接收
        receiver = new ForceOfflineReceiver();
        registerReceiver(receiver,intentFilter);  //注册广播接收器
    }
(2)注销广播
    @Override
    protected void onPause() {
        super.onPause();
        if(receiver != null){
            unregisterReceiver(receiver);  //注销广播接收器
            receiver = null;
        }
    }

需要注意的是: registerReceiver()和 unregisterReceiver()需要成对出现,否则可能导致已经注册的 receiver 没有在合适的时机注销,导致内存泄漏,占用内存空间。

引申问题:

如果注册写在onResume,反注册写在onDestory会造成的后果:

Activity 的生命周期不对应,可能出现多次 onResume 造成 receiver 注册多个,但最终只注销一个,其余 receiver 产生内存泄漏。

(3)在对话框窗口中设置点击其他地方不可取消弹窗,并调用ActivityCollector.finishAll()消除所有Activity后返回登陆界面。
//    对话框弹窗
    static class ForceOfflineReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setTitle("Warning");
            builder.setMessage("您被迫脱机。请尝试再次登录。");
            builder.setCancelable(false);//点击其他地方不可取消弹窗 
//为对话框注册确定按钮
            builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int watch) {
                    ActivityCollector.finishAll();
                    Intent intent1 = new Intent(context,LoginActivity.class);
                    context.startActivity(intent1);
                }
            });
            builder.show();
        }
    }

  • MainActivity发送广播

在此活动中仅点击按键发送一个广播,强制下线的逻辑应写在接收器中,这样强制下线的功能就不会依附于任何界面,当有接收器接到广播后,即可完成强制下线。

注册静态接收器无法完成在不同活动中获取不同广播,则需要在BaseActivity中注册动态广播接收器。

        forceOffline.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
//                发送广播用于通知程序强制用户下线
//                强制下线的代码写在接收器中,只要发送广播则可完成强制下线
                Intent intent = new
                        Intent("com.example.broadcastbestpractice.FORCE_OFFLINE");
                Toast.makeText(MainActivity.this,"发送广播",Toast.LENGTH_SHORT).show();
                sendBroadcast(intent);  //发送广播
            }
        });

Demo参考:

https://download.csdn.net/download/shanhe_yuchuan/87140881