新建BroadcastBestPractice项目java
建立ActivityCollector类管理全部的活动,代码以下:android
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(); } }
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); } }
<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,用于输入密码。第三行是一个按钮,用来登陆。app
接下来修改LoginActivity中的代码:ide
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(); } } }); } }
<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
。经过这个广播,咱们实现强制下线,这样强制下线功能不会依附任何界面,无论在程序任何地方,只要发出这样一条广播,就能够完成强制下线操做。布局
因为广播接收器须要弹出一个对话框来阻塞用户的正常操做,但若是建立的是一个静态注册的广播接收器,是没法在onReceive()方法中弹出对话框这样的UI控件的(为何?)。而咱们也不能在每一个活动中都去注册这样一个广播接收器。可是这个时候,咱们能够在BaseActivity中建立一个广播接收器就能够实现全部的活动中都有.(由于全部的活动都继承自BaseActivity)ui
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(); } } }
<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这个父类,当须要对子类作某些相同的操做时候,就实现一个父类来实现相同操做。这很重要。this