新建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