目錄
一惹谐、廣播
(一)廣播接收者
(二)自定義廣播的發(fā)送與接收
(三)有序廣播和無序廣播
二是整、服務(wù)
(一)基礎(chǔ)知識(shí)
(二)測(cè)試
三铡羡、補(bǔ)充
1、主要參考自:https://b23.tv/Flmxaa
2榛泛、內(nèi)容如果有不對(duì)的蝌蹂,希望可以指出或補(bǔ)充噩斟。
3曹锨、新知識(shí)。
一剃允、廣播
(一)廣播接收者
① 概述
廣播接收者(BroadcastReceiver):Android系統(tǒng)中內(nèi)置了很多廣播沛简,列如手機(jī)的開機(jī)完成、電池電量不足時(shí)都會(huì)發(fā)送一條廣播斥废。為了監(jiān)聽來自系統(tǒng)或者應(yīng)用程序的廣播事件椒楣,Android系統(tǒng)提供了廣播接收者組件(四大組件之一)。當(dāng)Android系統(tǒng)產(chǎn)生一個(gè)廣播事件時(shí)牡肉,可以有多個(gè)對(duì)應(yīng)的廣播接收者接收并進(jìn)行處理捧灰。相當(dāng)于是接收電臺(tái)消息的收音機(jī)。
特點(diǎn):一對(duì)多(如一個(gè)電臺(tái)的發(fā)出的頻率统锤,可以被多個(gè)收音機(jī)接收到)毛俏,消息是單向的(如收音機(jī)只能接收消息)。
② 測(cè)試
1 創(chuàng)建廣播接收者饲窿。
2 動(dòng)態(tài)注冊(cè)廣播接收者-創(chuàng)建
靜態(tài)的注冊(cè):系統(tǒng)一般會(huì)自動(dòng)創(chuàng)建煌寇,在項(xiàng)目清單文件里。
動(dòng)態(tài)注冊(cè)的特點(diǎn):只有當(dāng)注冊(cè)廣播接收者的組件活著的時(shí)候(存在)逾雄,對(duì)應(yīng)的廣播接收者才會(huì)接收到廣播阀溶,這也是和靜態(tài)注冊(cè)的區(qū)別所在。
3 測(cè)試-攔截電話
① 布局
② 代碼部分
③ 運(yùn)行效果
項(xiàng)目清單文件
如下:
(二)自定義廣播的發(fā)送與接收
① 概述
當(dāng)系統(tǒng)提供的廣播不能滿足需求時(shí)鸦泳,可以自定義廣播(發(fā)送消息)银锻,同時(shí)需要編寫對(duì)應(yīng)的廣播接收者(監(jiān)聽消息)。
當(dāng)自定義廣播發(fā)送消息時(shí)做鹰,會(huì)存儲(chǔ)到公共消息區(qū)中击纬,而公共消息區(qū)中如果存在對(duì)應(yīng)的廣播接收者,就會(huì)及時(shí)的接收這條消息誊垢。
② 測(cè)試
1 布局以及MainActivity.java內(nèi)容
2 測(cè)試效果
和上面的測(cè)試一樣的道理掉弛,處理項(xiàng)目清單文件(聲明自定義的廣播事件的意圖)
運(yùn)行結(jié)果:
(三)有序廣播和無序廣播
① 概述
Android系統(tǒng)提供了兩種廣播類型症见,有序廣播和無序廣播,開發(fā)者可根據(jù)需求為程序設(shè)置不同的廣播類型殃饿。
有序廣播:按照接收者的優(yōu)先級(jí)接收谋作,只有一個(gè)廣播接收者能接收到消息,在此廣播接收者中邏輯執(zhí)行完畢后乎芳,才會(huì)繼續(xù)傳遞遵蚜。
無序廣播:是完全異步執(zhí)行,發(fā)送廣播時(shí)所有監(jiān)聽這個(gè)廣播的廣播接收者都會(huì)接收到此消息奈惑,但接收的順序不確定吭净。
有序廣播可以被攔截;無序廣播所有的廣播接收者都可以接收到消息肴甸。
② 測(cè)試-有序廣播
需要新建三個(gè)廣播接收者驾诈,以便更好的測(cè)試。這三個(gè)廣播接收者的設(shè)置都差不多驻粟,如:
1 布局略
2 運(yùn)行效果
項(xiàng)目清單文件
效果如下:
注:如果priority的數(shù)值相同(優(yōu)先級(jí)一樣)役电,那么就是在項(xiàng)目清單文件中最先聲明(位置在前面的)先收到消息。如果把高優(yōu)先級(jí)的廣播中斷了(在廣播接收者里編寫 攔截有序廣播:abortBroadcast(); )庶柿,優(yōu)先級(jí)較低的就不會(huì)再收到消息了村怪,但有方法(如下圖-在發(fā)送方法里編寫)可以強(qiáng)制廣播接收者接收到消息。
二浮庐、服務(wù)
Day12內(nèi)容甚负。
服務(wù)(Service)也是四大組件之一,可將它看作是一個(gè)沒界面的activity(一般用于后臺(tái)操作审残,如手機(jī)息屏后音樂的播放)梭域。
最大的特點(diǎn):可在后臺(tái)長(zhǎng)時(shí)間運(yùn)行。
(一)基礎(chǔ)知識(shí)
創(chuàng)建:同廣播接收者的創(chuàng)建類似(在程序包名上右擊選擇【New】→【Service】→【Service】→在彈出的窗口中輸入服務(wù)名稱或默認(rèn)即可)维苔;若采用自行創(chuàng)建Java類繼承Service類的方式創(chuàng)建服務(wù)碰辅,則需要手動(dòng)在項(xiàng)目清單文件中進(jìn)行注冊(cè)。
生命周期:也就是它從啟動(dòng)到關(guān)閉所經(jīng)歷的一個(gè)過程介时。轉(zhuǎn)↓
啟動(dòng)方式:
① 通過startService()方法:服務(wù)會(huì)長(zhǎng)期運(yùn)行在后臺(tái)没宾,且服務(wù)的狀態(tài)與開啟者的狀態(tài)無關(guān),也就是即使啟動(dòng)服務(wù)的組件已被銷毀沸柔,服務(wù)會(huì)依舊運(yùn)行循衰。需要自身調(diào)用stopSelf()方法或其他組件調(diào)用stopService()方法時(shí)服務(wù)才能停止。
② 通過bindService()方法:服務(wù)會(huì)與組件綁定褐澎。需要調(diào)用onUnbind()方法解除綁定之后才會(huì)被銷毀会钝。注:如果要長(zhǎng)期存在,就需要在綁定之前用startService啟動(dòng)服務(wù)(結(jié)合使用)。
(二)測(cè)試
① startService啟動(dòng)Service
1 布局
2 服務(wù)類
3 展示結(jié)果
總結(jié):onCreate()表示的是當(dāng)服務(wù)創(chuàng)建的時(shí)候執(zhí)行(創(chuàng)建成功了就不會(huì)再有作用了)迁酸,只調(diào)用一次先鱼;多次執(zhí)行開啟服務(wù)(只要服務(wù)還是啟動(dòng)著的)會(huì)多次調(diào)用onStartCommand()且只是復(fù)用前面產(chǎn)生的service對(duì)象,不會(huì)新建新service對(duì)象奸鬓;onDestroy()表示的是關(guān)閉服務(wù)焙畔,同onCreate()一樣的道理,只調(diào)用一次串远。
② bindService啟動(dòng)Service
1 布局略(與①的布局設(shè)置同理)
2 代碼
① MyService.java
在OnBind()方法中需要返回一個(gè)IBinder的實(shí)例宏多,否則監(jiān)聽連接狀態(tài)的方法就不會(huì)調(diào)用。
package com.example.testservice;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
public MyService() { }
//定義onBinder方法所返回的對(duì)象實(shí)例
//創(chuàng)建服務(wù)代理 調(diào)用服務(wù)中的方法
class MyBinder extends Binder{
//可以間接調(diào)用到service里面的相關(guān)方法
public void callTestInService(){
testInService();
}
}
public void testInService(){
Log.i("MyService","自定義方法澡罚,testInService()");
}
@Override
//IBinder是一個(gè)接口 可進(jìn)行跨進(jìn)程訪問(遠(yuǎn)程調(diào)用)
public IBinder onBind(Intent intent) {
Log.i("MyService","綁定服務(wù)伸但,調(diào)用onBind()");
return new MyBinder();
}
@Override
public void onCreate() {
super.onCreate();
Log.i("MyService","創(chuàng)建服務(wù),調(diào)用onCreate()");
}
@Override
//解綁
public boolean onUnbind(Intent intent) {
Log.i("MyService","解綁服務(wù)留搔,調(diào)用onUnbind()");
return super.onUnbind(intent);
}
}
② MainActivity.java
package com.example.testservice;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private MyService.MyBinder myBinder;
private MyTest mytest;
@Override
//自帶
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//綁定(開啟)服務(wù)
public void btnBind(View view){
if(mytest == null){
mytest = new MyTest();
}
Intent intent = new Intent(this,MyService.class);
//參數(shù)1:用于指定要啟動(dòng)的service更胖,參數(shù)2:監(jiān)聽調(diào)用者與service間的連接狀態(tài),
// 參數(shù)3:指定綁定時(shí)是否自動(dòng)創(chuàng)建service
bindService(intent,mytest,BIND_AUTO_CREATE);
}
//服務(wù)連接時(shí)執(zhí)行
private class MyTest implements ServiceConnection{
@Override
//當(dāng)成功綁定服務(wù)時(shí)調(diào)用催式,返回MyService里面的Ibinder對(duì)象
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (MyService.MyBinder) service;
Log.i("MainActivity","服務(wù)成功綁定函喉,內(nèi)存地址為:"+myBinder.toString());
}
//當(dāng)服務(wù)失去連接時(shí),調(diào)用的方法
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("MainActivity","服務(wù)失去連接");
}
}
//調(diào)用服務(wù)中的方法
public void btnCall(View view){
//訪問到MyService里的callTestInService()方法
myBinder.callTestInService();
}
//解綁服務(wù)
public void btnUnbind(View view){
//需要判斷是因?yàn)椋航獬壎〞r(shí)就需要接收ServiceConnection
if(mytest != null){
unbindService(mytest);
mytest = null;
}
}
}
3 展示結(jié)果
總結(jié):多次啟動(dòng)服務(wù)荣月,onBind()只被調(diào)用一次。
三梳毙、補(bǔ)充
1哺窄、Android的四大組件,只要被定義了账锹,就必須在AndroidManifest.xml(清單文件)中注冊(cè)萌业。一般,系統(tǒng)都會(huì)自動(dòng)注冊(cè)奸柬。