知識點目錄
知識點回顧
在網絡通信裏,在一個IP網絡範圍中,最大的IP地址是被保留作爲廣播地址來使用的。例如:某個網絡的IP範圍是192.168.0.XXX,子網掩碼是255.255.255.0,那麼這個網絡的廣播地址就是192.168.0.255。廣播數據包會被髮送到同一網絡上的所有端口,在該網絡中的每臺主機都會接收到這個廣播。
爲了方便進行系統級別的消息通知,Android也引入了一套類似的廣播消息機制。
5.1 廣播機制
Android中的廣播主要分爲兩種類型:標準廣播和有序廣播。
標準廣播
完全異步執行!!!在廣播發出後,所有的廣播接收器幾乎在同一時刻接受到這條廣播信息。
特點:廣播效率高、沒有任何先後順序、無法被攔截
有序廣播
同步執行!!!廣播發出後,同一時刻只會有一個廣播接收器收到這條廣播消息,當這個廣播接收器中的邏輯執行完畢後,廣播纔會繼續傳遞。
特點:廣播接收器有先後順序,優先級高的廣播接收器先收到廣播消息,可以被優先級高的廣播接收器攔截。
5.2 接收系統廣播
Android內置了很多系統級別的廣播:
-
開機廣播
-
電池電量發生變化廣播
-
時間或時區發生改變廣播
-
等等。。。
5.2.1 動態註冊監聽網絡變化
廣播接收器可以自由註冊自己感興趣的廣播進行註冊。註冊的方式有兩種:
-
代碼中註冊(也稱爲動態註冊)
-
AndroidManifest.xml中註冊(也稱爲靜態註冊)
動態註冊監聽網絡變化的步驟如下:
-
創建一個廣播接收器,繼承BroadcastReceiver,重寫onReceive()方法
class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isAvailable()) { Toast.makeText(context, "network is availabe", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, "network is unavailable", Toast.LENGTH_SHORT).show(); } } }
當接收到廣播時,onReceive()方法就會執行,所以具體的邏輯就是在這個方法裏處理。
-
在代碼中動態註冊(一般是在Activity的onCreate方法中註冊)
IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("android.net.com.CONNECTIVITY_CHANGE"); mNetworkChangeReceiver = new NetworkChangeReceiver(); registerReceiver(mNetworkChangeReceiver, intentFilter);
備註:訪問系統的網絡狀態需要聲明權限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
- 取消註冊
動態註冊的廣播接收器需要取消註冊,一般是在onDestroy()中取消
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mNetworkChangeReceiver);
}
效果圖:
通過命令發送網絡改變的廣播:
am broadcast -a android.net.com.CONNECTIVITY_CHANGE
在有網和沒有網絡時的效果如下圖所示:
5.2.2 靜態註冊實現開機廣播
動態註冊的廣播接收器可以自由的註冊和註銷,但有個缺點:必須在程序啓動後才能接收到廣播,因爲註冊的邏輯是寫在onCreate()方法中。
靜態廣播可以在程序未啓動的時候就能接收到廣播。
Android Studio提供了快捷方式來創建一個廣播接收器:右擊com.example.broadcasttest包—>New—>Other—>Broadcast Receiver,
Exported屬性表示是否允許這個廣播器接收本程序之外的廣播。
Enabled屬性表示是否啓用這個廣播接收器。
Source Language可以選擇用Java或Kotlin。
靜態註冊監聽開機廣播的步驟如下:
-
通過Android Studio快捷創建廣播接收器,並修改onReceive()中的邏輯
public class BootCompleteReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "Boot Complete", 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>
-
添加監聽系統開機廣播的權限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
效果圖:
通過命令發送開機廣播:
am broadcast -a android.intent.action.BOOT_COMPLETED
命令發送出去後的效果如下圖所示:
注意:
不要在onReceive()方法中添加過多的邏輯或者進行任何耗時操作,因爲廣播接收器中不允許開啓線程,當onReceive()方法運行了較長的時間而沒有結束時,程序就會報錯。
5.3 發送自定義廣播
廣播主要分爲標準廣播和有序廣播,下面分別來實踐下具體實現。
5.3.1 發送標準廣播
發送標準廣播的一般步驟如下:
-
定義個廣播接收器
public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show(); } }
-
到AndroidManifest.xml中定義廣播接收器接收的action
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="example.broadcasttest"> <application ...... <receiver android:name=".MyBroadcastReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.example.broadcasttest.MY_BROADCAST"/> </intent-filter> </receiver> ...... </application> </manifest>
-
定義一個發送廣播的觸發點,並調用sendBroadcast()發送廣播
Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent("com.example.broadcasttest.MY_BROADCASTT"); sendBroadcast(intent); } });
效果圖:
備註:由於廣播是使用Intent進行傳遞的,所以還可以在Intent中攜帶一些數據傳遞給廣播接收器。
5.3.2 發送有序廣播
發送有序廣播的步驟跟上面發送標準廣播的步驟一樣,只是調用的方法不一樣。
- 使用sendOrderedBroadcast(intent,null)方法發送有序廣播
參數一:intent的對象
參數二:與權限相關的字符串,一般傳入null就行
-
通過android.priority設置廣播接收器的優先級
<receiver android:name=".MyBroadcastReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="100"> <action android:name="com.example.broadcasttest.MY_BROADCASTT"/> </intent-filter> </receiver>
-
可以調用abortBroadcast()方法截斷廣播
5.4 使用本地廣播
廣播是可以跨進程通信的,那麼攜帶的數據就有可能被其他程序截獲,存在一定的安全性問題。因此Android引入了一套本地廣播機制。主要是使用一個LocalBroadcastManager來對廣播進行管理。
主要用法如下:
public class MainActivity extends AppCompatActivity {
private LocalBroadcastManager mLocalBroadcastManager;
private LocalReceiver mLocalReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);//獲取實例
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCASTT");
mLocalBroadcastManager.sendBroadcast(intent);//發送本地廣播
}
});
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCASTT");
mLocalReceiver = new LocalReceiver();
mLocalBroadcastManager.registerReceiver(mLocalReceiver,intentFilter);//註冊本地廣播監聽器
}
@Override
protected void onDestroy() {
super.onDestroy();
mLocalBroadcastManager.unregisterReceiver(mLocalReceiver);//註銷本地廣播監聽器
}
class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();
}
}
}
本地廣播的使用其實跟動態註冊廣播是一樣的,只是多了一個LocalBroadcastManager對廣播的發送、註冊、註銷進行了管理。
本地廣播無法通過靜態註冊的方式來接收的,因爲靜態註冊主要就是在程序未啓動時也能接收到廣播,而發送本地廣播時,程序肯定已經啓動了。
本地廣播的優勢
-
發送的廣播不會離開自己的程序,所以數據不會泄露
-
其它程序無法將廣播發送到我們程序的內部,所以不會有安全漏洞隱患
-
發送本地廣播比發送系統全局廣播更加高效
5.5 廣播的最佳實踐——實現強制下線功能
強制下線功能需求:先關閉所有的活動,然後回到登錄界面。
代碼已上傳到我的github上,需要的朋友可以點擊如下鏈接查看:
運行效果圖:
5.6 Git時間——初識版本控制工具
Git是一個開源的分佈式版本控制工具,開發者是Linux操作系統的作者Linus Torvalds。
5.6.1 安裝Git
Ubuntu系統
安裝命令如下:
sudo apt-get install git-core
Windows系統
下載地址:
點擊Download按鈕可以開始下載,下載完成後雙擊安裝包進行安裝,之後一直點擊“下一步”就可以完成安裝了。
5.6.2 創建代碼倉庫
Git可以在圖形上進行操作,但我們應該掌握Git的各種命令,因爲Git命令在不同的操作系統上都是通用的。
Linux系統是打開shell界面,Windows是打開Git Bash。
配置身份
首先應該配置身份,這樣在提交代碼的時候Git就可以知道誰提交的,具體命令如下
git config --global user.name salmonzhang
git config --global user.email [email protected]
這樣名字和郵箱就已經配置好了。
查看git用戶名和郵箱的命令是
git config --global user.name
git config --global user.email
創建代碼倉庫的命令是:
git init
在項目的根目錄下執行git init命令後會生成一個隱藏的.git文件夾,該文件夾主要用來記錄本地所有的Git操作。如果要刪除本地倉庫,也只需要刪除這個文件夾就行了。
5.6.3 提交本地代碼
主要用到的是:
git add 和 git commit
add後面可以是文件名或者目錄,commit後面通過-m參數來加上提交的描述信息。
5.7 小結與點評
本章主要學習了Android的廣播機制,掌握了接收廣播、發送自定義廣播和本地廣播的使用方法。還學習了一點Git的基本知識。