接下来修改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(); //获取密码输入框的信息 if(account.equals("admin")&&password.equals("password")){ //判断输入是否正确 Intent intent=new Intent(LoginActivity.this,MainActivity.class); startActivity(intent); finish(); } else{ Toast.makeText(LoginActivity.this, "输入有误,请重新输入", Toast.LENGTH_SHORT).show(); } } }); } }
这里我们模拟登录时的界面,首先将 LoginActivity 的继承结构改为继承自 BaseActivity ,然后调用了 findViewById() 方法分别获取到输入框中的信息,然后再登录按钮里使用了一个简单的if判断,这里并没有用到数据库等知识。
因此,你就可以将MainActivity理解成登录成功后进入的程序主界面了。这里我们并不需要在主界面添加什么花哨的功能,只需要加入强制下线即可。
修改activity_main.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" tools:context=".MainActivity"> <Button android:id="@+id/force_offline" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="强制下线按钮"/> </LinearLayout>
非常简单,只有一个按钮而已,用于出发强制下线功能。然后修改MainActivity中的代码。
public class MainActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button=(Button) findViewById(R.id.force_offline); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent("com.example.xiaxian"); sendBroadcast(intent); //发送广播 } }); }
同样也很简单,这里我们给按钮注册了个监听事件,并且在点击事件里发送了一条广播,广播的值为com.example.xiaxian,这条广播就是通知程序强制用户下线的。也就是说,强制下线的功能并不是写在MainActivity里的,而是应该写在接收这条广播的广播接收器里面,这样强制用户下线的功能就不会依附于任何界面,不管是在程序的任何地方,只需要发出这样一条广播,可以完成强制下线的操作了。
那么接下来的操作,毫无疑问就是需要创建一个广播接收器来接收这条强制下线广播,唯一的问题就是,应该在哪里创建呢?由于广播接收器需要弹出一个对话框来阻塞用户的正常操作,但如果创建的是一个静态注册的广播接收器,是没有办法在 onReceive() 方法里弹出对话框的这样的UI操作的,而我没问显然也不可能在每个活动中都去注册一个动态的广播接收器。
解决办法就是,只需要在BaseActivity中动态注册一个广播接收器就可以了,因为所有的活动都是继承自BaseActivity的。
修改BaseActivity中的代码,如下所示:
public class BaseActivity extends AppCompatActivity { private ForceOfflineReceiver receiver; protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityCollector.addActivity(this); } protected void onResume(){ super.onResume(); IntentFilter intentFilter=new IntentFilter(); intentFilter.addAction("com.example.xiaxian"); receiver=new ForceOfflineReceiver(); registerReceiver(receiver,intentFilter); } @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 agaun"); //内容 builder.setCancelable(false); //不可取消活动(即无法通过返回键取消活动) builder.setPositiveButton("OK",new DialogInterface.OnClickListener(){ //对话框注册确定按钮 @Override public void onClick(DialogInterface dialog, int which) { ActivityCollector.finish(); //强制下线,即销毁所有活动 Intent intent=new Intent(context,LoginActivity.class); context.startActivity(intent); //重新启动LoginActivity } }); builder.show(); } } }
先看一下ForceOfflineReceiver中的代码吧,这次,我们先用 AlertDialog.Builder来构建了一个对话框,注意这一定要调用 setCancelable() 方法将对话框设置为不可取消,否则用户点一下返回键就可以关闭对话框并据需使用程序了。然后使用setPositiveButton()方法来给用户对话框注册确定按钮,当用户点击了确定按钮时,就调用强制下线功能来销毁所有活动,并重新启动登录界面。
再来看一下我们是怎么注册ForeOfflineReceiver这个广播接收器,可以看到,这里重写了onResume()和 onPause() 这两个活动得生命周期函数,然后分别在这两个方法里面注册和取消注册了 ForeOfflineReceiver。
为什么要这样写呢?
因为我们要始终保证只有处于栈顶的活动才能接受到这条强制下线广播,非栈顶的活动没必要去接受这条广播,所以写 onRemove 和 onPause() 方法里就可以很好的解决这个问题,当一个活动失去栈顶位置是就会自动取消广播接收器的注册。
这样的话,所有强制下线的逻辑就已经完成了,接下来我们换需要对AndroidManifest.xml文件进行修改,代码如下所示。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.a15094.broadcastbestpractice"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" 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>
好了,现在我们来试一下吧。
初学Android,互相学习啦。。