Android广播时间——实现强制下线功能
思路:强制下线功能需要先关闭掉所有的活动,然后回到登录界面。
步骤
新建BroadcastBestPractice项目
1.关闭所有活动
创建ActivityCollector类管理所有的活动,代码如下:
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();
    }
}
2.创建BaseActivity类作为所有活动的父类,因为需要用ActivityCollector管理所有活动代码如下:
public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityCollector.addActivity(this);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }
}
3.创建登录界面活动,新建LoginActivity,编辑其布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:textSize="18sp"
            android:text="Account:"/>
        <EditText
            android:id="@+id/account"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:textSize="18sp"
            android:text="Password:"/>
        <EditText
            android:id="@+id/password"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"
            android:inputType="textPassword"/>
    </LinearLayout>
    <Button
        android:id="@+id/login"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="Login"/>
</LinearLayout>

最外层是纵向的LinearLayout,里面包含三行子元素。第一行是横向的LinearLayout,用于输入账号信息。第二行是横向的LinearLayout,用于输入密码。第三行是一个按钮,用来登录。
接下来修改LoginActivity中的代码:
public class LoginActivity extends BaseActivity {
    private EditText accountEdit;
    private EditText passwordEdit;
    private Button login;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        accountEdit=(EditText)findViewById(R.id.account);
        passwordEdit=(EditText)findViewById(R.id.password);
        login=(Button)findViewById(R.id.login);
        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String account=accountEdit.getText().toString();
                String password=passwordEdit.getText().toString();
                //如果账号是admin且密码是123456,就认为登录成功
                if(account.equals("admin")&&password.equals("123456")){
                    Intent intent=new Intent(LoginActivity.this,MainActivity.class);//跳转到MainActivity
                    startActivity(intent);
                    finish();
                }else{
                    Toast.makeText(LoginActivity.this,"account or password is invald",Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}
4.修改activity_main.xml中的代码和MainActivity(所有的活动都要继承BaseActivity)中的代码,加入强制下线功能
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/force_offline"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Send force offline broadcast"/>
</LinearLayout>
public class MainActivity extends BaseActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button 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);
            }
        });
    }
}
代码十分简单但这里有个重点,我们点击按钮发送广播com.example.broadcastbestpractice.FORCE_OFFLINE。通过这个广播,我们实现强制下线,这样强制下线功能不会依附任何界面,不管在程序任何地方,只要发出这样一条广播,就可以完成强制下线操作。
5.创建广播接收器
由于广播接收器需要弹出一个对话框来阻塞用户的正常操作,但如果创建的是一个静态注册的广播接收器,是无法在onReceive()方法中弹出对话框这样的UI控件的(为什么?)。而我们也不能在每个活动中都去注册这样一个广播接收器。但是这个时候,我们可以在BaseActivity中创建一个广播接收器就可以实现所有的活动中都有.(因为所有的活动都继承自BaseActivity)
public class BaseActivity extends AppCompatActivity {
    private ForceOffLineReceiver receiver;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityCollector.addActivity(this);
    }
    //注册写在onResume()中
    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter=new IntentFilter();
        intentFilter.addAction("com.example.a51104.broadcastbestpractice.FORCE_OFFLINE");
        receiver=new ForceOffLineReceiver();
        registerReceiver(receiver,intentFilter);
    }
    //取消注册写在onPause()中,因为只有栈顶活动才需要接收那个广播
    @Override
    protected void onPause() {
        super.onPause();
        if(receiver!=null){
            unregisterReceiver(receiver);
            receiver=null;
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }
    class ForceOffLineReceiver 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) {
                    ActivityCollector.finishAll();//取消所有活动
                    Intent i=new Intent(context,LoginActivity.class);
                    context.startActivity(i);//重新启动LoginActivity
                }
            });
            builder.show();
        }
    }
}
6.修改AndroidManifest.xml,将LoginActivity设置为主活动
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcastbestpractice">
    <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">
        </activity>
        <activity android:name=".LoginActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
总结
其实强制下线功能可以感觉到广播的厉害,就是不用对每个活动都注册。第二个就是BaseActivity这个父类,当需要对子类做某些相同的操作时候,就实现一个父类来实现相同操作。这很重要。
Android广播时间——实现强制下线功能的更多相关文章
- Android学习总结(八)———— 广播的最佳实践(实现强制下线功能)
		一.基本概念 强制下线功能功能应该算是比较常见的了,很多应用程序都具备这个功能,比如你的QQ号或者微信号在别处登录了,就会将你强制挤下线.只需要在界面上弹出一个对话框,让用户无法进行任何其他的操作,必 ... 
- android#boardcast#广播实现强制下线功能
		参考自<第一行代码>——郭霖 强制下线功能需要先关闭掉所有的活动(Activity),然后回到登录界面.先创建一个ActivityCollector类用于管理所有的活动,代码如下所示: p ... 
- Android学习之基础知识八—Android广播机制实践(实现强制下线功能)
		强制下线功能算是比较常见的了,很多的应用程序都具备这个功能,比如你的QQ号在别处登录了,就会将你强制挤下线.实现强制下线功能的思路比较简单,只需要在界面上弹出一个对话框,让用户无法进行任何操作,必须要 ... 
- android: 实现强制下线功能
		强制下线功能应该算是比较常见的了,很多的应用程序都具备这个功能,比如你的 QQ 号在别处登录了,就会将你强制挤下线.其实实现强制下线功能的思路也比较简单,只需要 在界面上弹出一个对话框,让用户无法进行 ... 
- Android学习总结——强制下线功能(广播)
		最近一口气买了好几本书,其中Android的<第一行代码>觉得真心不错,学到这个内容,顺便做个总结,加深印象. 强制下线的基本思想就是在界面上弹出一个对话框,让用户必须点击确定按钮跳转到登 ... 
- Android学习笔记(十五)——实战:强制下线
		//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 实现强制下线功能的思路也比较简单,只需要在界面上弹出一个对话框, 让用户无法进行任何其他操作, 必须要点击对话 ... 
- 让最新的 Android Q Beta 3 强制重启的 Project Mainline,到底是什么?
		一. 序 最新的 Android 版本 Q,已经发布了 Android Q Beta 3,虽然没有正式发布,但是不少用户已经加入了测试计划,抢先体验 Android Q 的新功能. 近期不少体验用户反 ... 
- Android 广播大全 Intent Action 事件详解
		Android 广播大全 Intent Action 事件详解 投稿:mrr 字体:[增加 减小] 类型:转载 时间:2015-10-20我要评论 这篇文章主要给大家介绍Android 广播大全 In ... 
- Android随笔之——Android广播机制Broadcast详解
		在Android中,有一些操作完成以后,会发送广播,比如说发出一条短信,或打出一个电话,如果某个程序接收了这个广播,就会做相应的处理.这个广播跟我们传统意义中的电台广播有些相似之处.之所以叫做广播,就 ... 
随机推荐
- Flutter环境安装,ios真机调试
			MAC: 下载Flutter,官网的可能很慢.可以去我的网盘下载, 提取码: 3t6y. 下载完的包会在~/Downloads目录下,我们移到~/opt/flutter目录下. mkdir ./opt ... 
- (转载)基于BIGINT溢出错误的SQL注入
			我对于通过MySQL错误提取数据的新技术非常感兴趣,而本文中要介绍的就是这样一种技术.当我考察MySQL的整数处理方式的时候,突然对如何使其发生溢出产生了浓厚的兴趣.下面,我们来看看MySQL是如何存 ... 
- Mysql数据操作指令
			-----多数据插入-----只要写一次insert指令,但是可以直接插入多条记录insert into table values(),(),(); 主键冲突我们插入值的时候,主键中已经存在某个值,插 ... 
- pytorch torchversion自带的数据集
			from torchvision.datasets import MNIST # import torchvision # torchvision.datasets. #准备数据集 mnist = M ... 
- tp5--开发规范
			在日常开发的过程中,写代码都要有一定的规范,不然可读取就太差了,所以为了以后的维护.对接,好的代码规定是必须的. 以下是我自己对自己提出的要求: 全部: 1) 每个方法都要写好备注(@retrun作 ... 
- 微信小程序入门(持续更新)
			微信小程序的主要文件介绍: . js:脚本文件 .json:配置文件 .wxss:样式表文件 .wxml:页面 微信小程序差不多也是和mvc模式差不多的,采用数据和页面分离的模式,在js上写的数据可以 ... 
- Ansible Jinja2 模板使用
			Ansible Jinja2 模板使用.语法与使用案例 主机规划 添加用户账号 说明: 1. 运维人员使用的登录账号: 2. 所有的业务都放在 /app/ 下「yun用户的家目录」,避免业务数据乱放: ... 
- Java多线程并发系列之闭锁(Latch)和栅栏(CyclicBarrier)
			JAVA并发包中有三个类用于同步一批线程的行为,分别是闭锁(Latch),信号灯(Semaphore)和栅栏(CyclicBarrier).本贴主要说明闭锁(Latch)和栅栏(CyclicBarri ... 
- Golang——Cron 定时任务
			开门见山写一个 package main import ( "fmt" "github.com/robfig/cron" "log" &qu ... 
- SaltStack的数据系统
			一.SaltStack数据系统的分类 1.Grains(收集的是静态数据) 官方使用文档:https://www.unixhot.com/docs/saltstack/topics/targeting ... 
