最近一口气买了好几本书,其中Android的《第一行代码》觉得真心不错,学到这个内容,顺便做个总结,加深印象。

强制下线的基本思想就是在界面上弹出一个对话框,让用户必须点击确定按钮跳转到登录界面,这里就有一个问题,通知强制下线时可能处于任何一个界面,我们总不能在每个界面都要实现弹出对话框的逻辑,所以这里可以利用广播来实现。

首先强制下线需要关闭所有活动,然后回到登录界面,所以我们这里创建一个ActivityCollector集合类来管理所有的活动,代码如下:

package com.example.xch.broadcastpractice;

import android.app.Activity;

import java.util.ArrayList;
import java.util.List; /**
* Created by xch on 2016/12/15.
*/ public class ActivityCollector {
public static List<Activity> activityList=new ArrayList<Activity>();
//将Activity加入集合
public static void addActivity(Activity activity){
activityList.add(activity);
}
//将Activity移除集合
public static void removeActivity(Activity activity){
activityList.remove(activity);
}
//关闭所有Activity
public static void finishAll(){
for(Activity activity:activityList){
if(!activity.isFinishing()){
activity.finish();
}
}
}
}

然后创建BaseActivity类作为所有活动的父类:这个类继承自Activity,然后重写onCreate()方法调用ActivityCollector的addActivity()方法将当前正在创建的活动添加到活动管理器中,同理在onDestroy()中移除活动。

package com.example.xch.broadcastpractice;

import android.app.Activity;
import android.os.Bundle; /**
* 作为所有活动的父类
* Created by xch on 2016/12/15.
*/ public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCollector.addActivity(this);//将Activity加入集合
} @Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);//将Activity从集合移除
}
}

现在我们就可以随时随地将所有活动移除了。

下面我们模拟一个简单的登录功能,首先创建登录布局:activity_login.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.xch.broadcastpractice.LoginActivity"> <!-- Login progress -->
<ProgressBar
android:id="@+id/login_progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:visibility="gone" /> <ScrollView
android:id="@+id/login_form"
android:layout_width="match_parent"
android:layout_height="match_parent"> <LinearLayout
android:id="@+id/email_login_form"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"> <android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"> <AutoCompleteTextView
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_email"
android:inputType="textEmailAddress"
android:maxLines="1"
android:singleLine="true" /> </android.support.design.widget.TextInputLayout> <android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"> <EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:imeActionId="@+id/login"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" /> </android.support.design.widget.TextInputLayout> <Button
android:id="@+id/login"
style="?android:textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/action_sign_in"
android:textStyle="bold" /> </LinearLayout>
</ScrollView>
</LinearLayout>

接下来编写登录界面的活动,新建LoginActivity继承自BaseActivity,代码如下:

package com.example.xch.broadcastpractice;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast; /**
* Created by xch on 2016/12/15.
*/ public class LoginActivity extends BaseActivity {
private TextView usename;
private EditText password;
private Button login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
usename= (TextView) findViewById(R.id.username);
password= (EditText) findViewById(R.id.password);
login= (Button) findViewById(R.id.login);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String account=usename.getText().toString();
String pwd=password.getText().toString();
if(account.equals("xch_yang@126.com")&&pwd.equals("123456")){
Intent intent=new Intent(LoginActivity.this,MainActivity.class);
startActivity(intent);
finish();
}else{
Toast.makeText(LoginActivity.this,"用户名或密码错误!",Toast.LENGTH_SHORT).show();
}
}
});
}
}

这里直接使用一个默认值,如果登录成功就跳到MainActivity,否则就登录失败。所以我们在MainActivity中添加强制下线的功能。activity_main:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.xch.broadcastpractice.MainActivity"> <TextView
android:text="恭喜你,登录成功!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="119dp"
android:layout_marginStart="119dp"
android:layout_marginTop="15dp"
android:id="@+id/textView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" /> <Button
android:text="强制下线"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="35dp"
android:id="@+id/force_offline"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="105dp"
android:layout_marginStart="105dp" />
</RelativeLayout>

MainActivity.class:

package com.example.xch.broadcastpractice;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button; public class MainActivity extends BaseActivity {
private Button force_offline; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
force_offline=(Button) findViewById(R.id.force_offline);
force_offline.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("com.example.FORCE_OFFLINE");//发送广播,在广播接收器里实现强制下线的逻辑
sendBroadcast(intent);
}
});
}
}

这里很简单,就是在按钮事件里发送了一条广播,然后在广播接收器里实现强制下线的逻辑。接下来创建广播接收器ForceOfflineReceiver继承自Broadcast。

package com.example.xch.broadcastpractice;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.WindowManager; /**
* Created by xch on 2016/12/15.
*/ public class ForceOfflineReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
//实现强制下线的逻辑
AlertDialog.Builder dialogBuilder=new AlertDialog.Builder(context);//使用AlertDialog.Builder构建一个对话框
dialogBuilder.setTitle("warning");
dialogBuilder.setMessage("你已经被强制下线,请重新登录");
dialogBuilder.setCancelable(false);//将对话框设置为不可取消
dialogBuilder.setPositiveButton("确定", 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); //重新启动登录界面
}
});
AlertDialog alertDialog=dialogBuilder.create();
//设置AlertDialog类型,保证在广播接收器中可以正常弹出
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
}
}

这里要注意的是,由于我们是在广播中启动活动LoginActivity,因此一定要给Intent加上FLAG_ACTIVITY_NEW_TASK标志。最后还要把对话框的类型设置成TYPE_SYSTEM_ALERT,不然它将无法在广播接受器中弹出。

接下来对AndroidManifest.xml进行配置:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.xch.broadcastpractice"> <!-- To auto-complete the email text field in the login form with the user's emails -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" /> <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=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"></activity>
<receiver android:name=".ForceOfflineReceiver">
<intent-filter>
<action android:name="com.example.FORCE_OFFLINE"/>
</intent-filter>
</receiver>
</application> </manifest>

由于我们在广播接收器里弹出了一个系统级别的对话框,因此要声明权限:android.permission.SYSTEM_ALERT_WINDOW,最后别忘了注册广播ForceOfflineReceiver和活动LoginActivity。

运行程序,进入登录界面:

成功登录之后进入程序主界面:

点击强制下线按钮,就会发出一条强制下线的广播,广播接受器接收广播之后就会弹出提示框,用户点击确定之后就会重新回到登录界面:

Android学习总结——强制下线功能(广播)的更多相关文章

  1. Android学习总结(八)———— 广播的最佳实践(实现强制下线功能)

    一.基本概念 强制下线功能功能应该算是比较常见的了,很多应用程序都具备这个功能,比如你的QQ号或者微信号在别处登录了,就会将你强制挤下线.只需要在界面上弹出一个对话框,让用户无法进行任何其他的操作,必 ...

  2. Android学习之基础知识八—Android广播机制实践(实现强制下线功能)

    强制下线功能算是比较常见的了,很多的应用程序都具备这个功能,比如你的QQ号在别处登录了,就会将你强制挤下线.实现强制下线功能的思路比较简单,只需要在界面上弹出一个对话框,让用户无法进行任何操作,必须要 ...

  3. android#boardcast#广播实现强制下线功能

    参考自<第一行代码>——郭霖 强制下线功能需要先关闭掉所有的活动(Activity),然后回到登录界面.先创建一个ActivityCollector类用于管理所有的活动,代码如下所示: p ...

  4. Android广播时间——实现强制下线功能

    目录 思路:强制下线功能需要先关闭掉所有的活动,然后回到登录界面. 步骤 1.关闭所有活动 2.创建BaseActivity类作为所有活动的父类,因为需要用ActivityCollector管理所有活 ...

  5. android: 实现强制下线功能

    强制下线功能应该算是比较常见的了,很多的应用程序都具备这个功能,比如你的 QQ 号在别处登录了,就会将你强制挤下线.其实实现强制下线功能的思路也比较简单,只需要 在界面上弹出一个对话框,让用户无法进行 ...

  6. Android学习笔记--Broadcast, BroadcastReceiver(广播)

    参考资料:http://www.cnblogs.com/playing/archive/2011/03/23/1992030.html 在 Android 中使用 Activity, Service, ...

  7. Android学习笔记(十三)——广播机制

     //此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! Android 中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接收到自己所关心的广播内容 ...

  8. android 学习随笔十八(广播与服务 )

    1.广播接收者注册 清单文件注册(Android四大组件都要在清单文件中注册) 一旦应用部署,广播接收者就生效了,直到用户手动停止应用或者应用被删除 广播接收者可以使用代码注册 需要广播接收者运行时, ...

  9. android 学习随笔十六(广播 )

    1.广播接收者 BroadcastReceiver 接收系统发出的广播 现实中的广播:电台为了传达一些消息,而发送的广播,通过广播携带要传达的消息,群众只要买一个收音机,就可以收到广播了  Andro ...

随机推荐

  1. Android全局变量使用

    1.通过一个Data.java实例类,能够实现全局数据保存,这里就不多说了,学Java的都知道. 2.Android特有的Application,是应用的入口,执行贯穿整个app执行过程,能够在这个类 ...

  2. HDU 4119Isabella's Message2011成都现场赛I题(字符串模拟)

    Isabella's Message Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  3. 如何使用easyUI

    一.简介 以下内容来自百度: jQuery EasyUI是一组基于jQuery的UI插件集合,而jQuery EasyUI的 目标就是帮助web开发者更轻松的打造出功能丰富并且美观的UI界面.开发者不 ...

  4. Android 自定义控件玩转字体变色 打造炫酷ViewPager指示器

    1.概述 本篇博客的产生呢,是因为,群里的哥们暖暖给我发了个效果图,然后问我该如何实现顶部ViewPager指示器的字体变色,该效果图是这样的: 大概是今天头条的app,神奇的地方就在于,切换View ...

  5. SQL通用函数-nvl-nvl2 -nvlif-nullif-coalesce-decode-case

    通用函数适用于任何类型数据(包括空值),一般用于实现空值处理.条件运算和多路分支结果,下面介绍其中常用的几种: nvl(exp1, exp2) 函数nvl(exp1, exp2)用于将空值转换为指定的 ...

  6. ORA-02447: cannot defer a constraint that is not deferrable

    一个constraint如果被定义成deferrable那么这个constraints可以在deferred和imediate两种状态相互转换. deferred只在transaction中有效,也就 ...

  7. C#多线程实践——线程同步

    下面的表格列展了.NET对协调或同步线程动作的可用的工具:                       简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程完成      ...

  8. poj3468 线段树+lazy标记

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 92921   ...

  9. JS中,如何查询一个对象的所有属性

    var res = ""; for(var p in object) { res += p + ","; } alert(res);

  10. 搭建hadoop2.6.0集群环境

    一.规划 (一)硬件资源 10.171.29.191 master 10.171.94.155  slave1 10.251.0.197 slave3 (二)基本资料 用户:  jediael 目录: ...