- 广播机制简介
- 接收系统广播
- 动态注册监听网络变化
- 静态注册实现开机启动
- AndroidManifest.xml
- BootCompleteReceiver.java
- 发送自定义广播
- 发送标准广播
- MyBroadcaseReceiver.java
- activity_main.xml
- MainActivity.java
- AndroidManifest.xml
- 发送有序广播
- AndroidMenifest.xml
- AnotherBroadcastReceiver.java
- MainActivity.java
- AndroidManifest.xml
- MyBroadcastReceiver.java
- 使用本地广播
- MainActivity.java
- 实现强制下线功能
- ActivityCollector.java
- BaseActivity.java
- activity_login.xml
- activity_main.xml
- MainActivity.java
- BaseActivity.java
- AndroidMenifest.xml
- LoginActivity>java
- Git时间——初始版本控制工具
广播机制简介
广播类型:标准广播和有序广播
- 标准广播(Normal broadcasts)是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序可言。这种广播的效率会比较高,但同时也意味着它是无法被截断的。
- 有序广播( Ordered broadcasts)是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器就无法收到广播消息了。
接收系统广播
Q:如何创建一个广播接收器呢?
其实只需要新建一个类,让它继承自Broadcast-Receiver,并重写父类的 onReceive()方法就行了。这样当有广播到来时,onReceive()方法就会得到执行。
动态注册监听网络变化
- 思路:在 MainActivity 中定义了一个内部类NetworkChangeReceiver,这个类是继承自BroadcastReceiver的,并重写了父类的onReceive()方法。这样每当网络状态发生变化时,onReceive()方法就会得到执行,并准确地告诉用户当前是否有网络
- 在onCreate()方法中:
- 创建一个IntentFilter的实例添加一个值为 android.net.conn.CONNECTIVITY_CHANGE的action,当网络状态发生变化时,系统发出的正是一条值为 android.net.conn.CONNECTIVITY_CHANGE的广播,也就是说广播接收器想要监听什么广播,就在这添加相应的action。
- 接下来创建一个
NetworkChangeReceiver
的实例,然后调用registerReceiver()
方法进行注册,将NetworkChangeReceiver的实例和IntentFilter的实例都传进去。 - 通过
getSystemService()
方法得到了ConnectivityManager
的实例,这是一个系统服务类,专门用于管理网络连接的。调用它的getActiveNetwork-Info()
方法可以得到NetworkInfo
的实例,接着调用NetworkInfo的isAvailable()
方法,就可以判断出当前是否有网络了,最后我们还是通过Toast的方式对用户进行提示。 - 用onDestroy()方法取消注册
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter();
//网络状态变化系统就发android.net.conn.CONNECTIVITY_CHANGE
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
class NetworkChangeReceiver extends BroadcastReceiver {
@Override
//网络状态变化提示
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"network changes",Toast.LENGTH_SHORT).show();
}
}
}
静态注册实现开机启动
注意:先运行一遍,然后关机,然后再重新开启这个手机(不是点小三角而是小手机!!),最后静等一会就会出现
AndroidManifest.xml
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
BootCompleteReceiver.java
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Boot Complete",Toast.LENGTH_SHORT).show();
}
}
发送自定义广播
发送标准广播
MyBroadcaseReceiver.java
用于接收广播
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received is MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
}
}
activity_main.xml
<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/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send Broadcast"/>
</LinearLayout>
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);
}
});
}
AndroidManifest.xml
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>
发送有序广播
新建BroadcastTest2
AndroidMenifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcasttest2">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.BroadcastTest2">
<receiver
android:name=".AnotherBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
AnotherBroadcastReceiver.java
public class AnotherBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received in AnotherBroadcastReceiver", Toast.LENGTH_SHORT).show();
}
}
MainActivity.java
回到BroadcastTest,发送有序广播
@Override
public void onClick(View view) {
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendOrderedBroadcast(intent,null);
}
AndroidManifest.xml
让广播接收器有先后android:priority
:优先级设置成100,保证在AnotherBroadcastReceiver之前收到广播
<intent-filter android:priority="100">
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>
MyBroadcastReceiver.java
about Broadcast()
截断广播
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received is MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
abortBroadcast();
}
使用本地广播
使用LocalBroadcastManager对广播进行管理,解决安全性问题
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
localBroadcastManager = LocalBroadcastManager.getInstance(this); //获取实例
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent); //发送本地广播
}
});
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver,intentFilter); //注册本地广播监听器
}
@Override
protected void onDestroy() {
super.onDestroy();
//unregisterReceiver(networkChangeReceiver);
localBroadcastManager.unregisterReceiver(localReceiver);
}
class NetworkChangeReceiver extends BroadcastReceiver {
@Override
//网络状态变化提示
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectionManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
if(networkInfo != null && networkInfo.isAvailable()){
Toast.makeText(context, "network is available", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"network is unavailable",Toast.LENGTH_SHORT).show();
}
}
}
private class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();
}
}
实现强制下线功能
ActivityCollector.java
用于管理所有的活动
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();
}
}
}
}
BaseActivity.java
作为所有活动的父类
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCollector.addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
}
activity_login.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp" >
<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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp">
<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>
activity_main.xml
button用于触发强制下线功能
<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>
MainActivity.java
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 view) {
Intent intent = new Intent("com.example.broadcastbestpractice.FORCE_OFFLINE");
sendBroadcast(intent);
}
});
}
}
BaseActivity.java
public class BaseActivity extends AppCompatActivity {
private ForceOfflineReceiver receiver;
@Override
protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCollector.addActivity(this);
}
@Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcastbestpractice.FORCE_OFFLINE");
receiver = new ForceOfflineReceiver();
registerReceiver(receiver,intentFilter);
}
@Override
protected void onPause() {
super.onPause();
if(receiver != null){
unregisterReceiver(receiver);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
private 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("您已下线,请重新登陆!");
builder.setCancelable(false);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ActivityCollector.finishAll(); //销毁所有活动
Intent intent = new Intent(context,LoginActivity.class);
context.startActivity(intent); //重新启动LoginActivity
}
});
builder.show();
}
}
}
AndroidMenifest.xml
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
LoginActivity>java
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 view) {
String account = accountEdit.getText().toString(); //获取编辑框的文字
String password = passwordEdit.getText().toString();
if(account.equals("sakura") && password.equals("123456")){
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
startActivity(intent);
finish();
}else{
Toast.makeText(LoginActivity.this,"账号或密码错误",Toast.LENGTH_SHORT).show();
}
}
});
}
}
Git时间——初始版本控制工具
git add build.gradle
:
这是添加单个文件的方法,那如果我们想添加某个目录呢?其实只需要在add后面加上目录名就可以了。比如将整个app目录下的所有文件都进行添加,就可以输人如下命令:
git add app
可是这样一个个地添加感觉还是有些复杂,有没有什么办法可以一次性就把所有的文件都添加好呢?当然可以,只需要在add的后面加上一个点,就表示添加所有的文件了,命令如下所示:
git add .
现在 BroadcastBestPractice项目下所有的文件都已经添加好了,我们可以来提交一下了,输入如下命令:
git commit -m "First commit . "
注意,在commit命令的后面,我们一定要通过-m参数来加上提交的描述信息,没有描述信息的提交被认为是不合法的。