第十章 Service與BroadcastReceiver

Service是Android四大組件中與Activity最相似的組件,他們都代表可執(zhí)行的程序,Service與Activity的區(qū)別在于:Service一直在后臺(tái)運(yùn)行,他沒(méi)有用戶界面,所以絕不會(huì)到前臺(tái)來(lái),一旦Service被啟動(dòng)起來(lái),他就與Activity一樣,他完全具有自己的生命周期。關(guān)于程序中Activity和Service的選擇標(biāo)準(zhǔn)是:如果某個(gè)程序需要在運(yùn)行時(shí)向用戶呈現(xiàn)某種界面,或者該程序需要與用戶交互,就需要使用Activity;否則就應(yīng)該考慮使用Service了。

開(kāi)發(fā)者開(kāi)發(fā)Service的步驟與開(kāi)發(fā)Activity的步驟很像,開(kāi)發(fā)Service組件需要先開(kāi)發(fā)一個(gè)Service子類,然后在AndroidManifest.xml文件中配置該Service,配置時(shí)通過(guò)<intent-filter...../>。元素指定它可被那些Intent啟動(dòng)。

Android系統(tǒng)本身提供了大量的Service組件,開(kāi)發(fā)者可通過(guò)這些系統(tǒng)Service來(lái)操作Android系統(tǒng)本身。

本章還將向讀者介紹BroadcastReceiver組件。BroadcastReceiver組件就像一個(gè)全局的事件監(jiān)聽(tīng)器,只不過(guò)用于監(jiān)聽(tīng)系統(tǒng)Broadcast。通過(guò)是BroadcastReceiver,即可在不同應(yīng)用程序之間通訊。

10.1 Service簡(jiǎn)介

Service組件也是可執(zhí)行得讓程序,他有自己的生命周期。創(chuàng)建、配置Service與創(chuàng)建、配置Activity的過(guò)程基本相似,下面詳細(xì)介紹Android Service的開(kāi)發(fā)。

10.1 創(chuàng)建、配置Service

就像開(kāi)發(fā)Activity需要兩個(gè)步驟:

(1)開(kāi)發(fā)Activity子類;

2、在AndroidManifest.xml文件中配置Activity。開(kāi)發(fā)Service也需要兩個(gè)步驟。

(1)定義一個(gè)繼承Service的子類。

(2)在AndroidManifest.xml文件中配置該Service

Service與Activity還有一些相似之處,它們都是從Content派生出來(lái)的,因此它們都可以調(diào)用Content里定義的如getResources、getContentResolver()等方法。

與Activity相似的是,Service中也定義了一系列生命周期方法,如下所示:

1、 IBinder onBind(Intent intent):該方法是Service之類必須實(shí)現(xiàn)的方法。該方法返回一個(gè)IBinder對(duì)象,應(yīng)用程序可通過(guò)該對(duì)象與Service組件通訊。

2、 void onCreat():在該Service第一次被創(chuàng)建后立即回調(diào)該方法。

3、 void onDestroy():在該Service第一次被創(chuàng)建后將立即回調(diào)該方法。

4、 void onStartCommand(Intent intent,int flags,int starId):該方法的在其版本是Void onStart(Intent intent,int startId),每次客服端調(diào)用startService(Intent)方法啟動(dòng)該Service時(shí)都會(huì)回調(diào)該方法。

5、 boolean onUnbind(Intent intent):當(dāng)該Service上綁定的所有客戶端都斷開(kāi)鏈接時(shí)將會(huì)回調(diào)該方法。

下面的類定義了一個(gè)Service

提示:

上面這個(gè)Service什么也沒(méi)干,但實(shí)際上它是Service組建的框架,如果希望Service組件做某些事情,那么只要在onCreat()或onStartCommand()方法中定義相關(guān)業(yè)務(wù)代碼即可。

定義了上面的Service之后,接下來(lái)需要在AndroidManifest.xml文件中配置該Service,配置Service使用

與配置Activity相似的是,配置Service時(shí)也可以為<service.../>元素配置<intent-filter.../>子文件,用于說(shuō)明該Service可被那些Intent啟動(dòng)。

從上面的配置片段不難看出,配置Service與配置Activity的差別并不大,只是配置Service使用<Service.../>,而且無(wú)需指定android:label屬性-------因?yàn)镾ervice沒(méi)有界面,總是位于后臺(tái)運(yùn)行,為該Service指定標(biāo)簽沒(méi)有太大的意義。

1、通過(guò)Content的startService()方法:通過(guò)該方法啟動(dòng)Service,訪問(wèn)者與Service沒(méi)有關(guān)聯(lián),即使訪問(wèn)者退出了,Service也仍然運(yùn)行。

2、通過(guò)Content的bindService()方法:使用該方法啟動(dòng)Service,訪問(wèn)者與Service綁定在一起,訪問(wèn)者退出了,Service也就終止了。

下面先示范第一種方式運(yùn)行Service

從上面程序中的粗字體代碼不難看出,啟動(dòng)、關(guān)閉Service十分簡(jiǎn)單,調(diào)用Content里定義的startService、stopService()方法即可啟動(dòng)、關(guān)閉Service。

提示:

可能讀者會(huì)注意到本程序使用了顯示Intent(直接指定要啟動(dòng)的目標(biāo)組件實(shí)現(xiàn)類)來(lái)啟動(dòng)Service,單本書第二版使用了隱士Intent啟動(dòng)Service。這是因?yàn)閺腁ndroid5.0開(kāi)始,Google要求必須使用顯示Intent啟動(dòng)Service組件。


運(yùn)行該程序,通過(guò)程序界面先啟動(dòng)Service,在關(guān)閉Service,將可以在AS的Logcat面板看到如上圖所示的輸出。

如果不關(guān)閉Service的情況下,連續(xù)三次單擊“啟動(dòng)Service”按鈕,

從上圖可以看出,每當(dāng)Service被創(chuàng)建時(shí)會(huì)回調(diào)onCreat()方法,每次Service被啟動(dòng)時(shí)都會(huì)回調(diào)onStartCommand()方法-----多次啟動(dòng)一個(gè)已有的Service組件將不會(huì)在回調(diào)onCreat()方法,但每次啟動(dòng)都會(huì)回調(diào)onStartCommand()。

10.1.3 綁定本地Service并與之通訊

當(dāng)程序通過(guò)starService()和stopService()啟動(dòng)、關(guān)閉Service時(shí),Service與訪問(wèn)者之間基本上不存在太多的關(guān)聯(lián),因此Service和訪問(wèn)者之間也無(wú)法進(jìn)行通訊、交換數(shù)據(jù)。

如果Service和調(diào)用者之間需要數(shù)據(jù)交換,則應(yīng)該使用bindService和unbindService()方法啟動(dòng)和關(guān)閉Service。

Content的bindService()方法完整的方法簽名是:bindService(Intent service,ServiceConnection conn,int flags),該方法的三個(gè)參數(shù)解釋如下。

1、Service:該參數(shù)通過(guò)Intent指定要啟動(dòng)的Service。

2、conn:該參數(shù)是一個(gè)Serviceconnection對(duì)象,該對(duì)象用于監(jiān)聽(tīng)訪問(wèn)者與Service之間的連接情況。當(dāng)訪問(wèn)者與Service之間連接成功時(shí)將回調(diào)該ServiceConnection對(duì)象的onServiceConnected(CompontName name,Ibinder service)方法;當(dāng)Service所在的宿主進(jìn)程由于異常終止或其他原因終止,導(dǎo)致該Service與訪問(wèn)者之間斷開(kāi)連接時(shí)回調(diào)該ServiceConnection對(duì)象的onServiceDisconnected(ComponentName name)方法。

注意:

當(dāng)調(diào)用者主動(dòng)通過(guò)unBindService()方法斷開(kāi)與Service的連接時(shí),ServiceConnection對(duì)象的onSrviceDisconnected(ComponentName name)方法并不會(huì)被調(diào)用。

flags:指定綁定時(shí)是否自動(dòng)創(chuàng)建Service(如果Service還未創(chuàng)建)。該參數(shù)可指定為0(不自動(dòng)創(chuàng)建)或BIND_AUTO_CREATE(自動(dòng)創(chuàng)建)。

注意到Serviceconnection對(duì)象的onServiceConnected()方法中有一個(gè)IBinder對(duì)象,該對(duì)象即可實(shí)現(xiàn)與被綁定Service之間的通訊。

當(dāng)開(kāi)發(fā)Service類時(shí),該service必須提供一個(gè)IBinder onBind(Intent intent)方法,在綁定本地Service情況下,onBind(Intent intent)方法返回的IBinder對(duì)象將會(huì)傳給ServiceConnection對(duì)象里onServiceConnected(CompontName name,Ibinder service)方法的Service參數(shù),這樣訪問(wèn)者就可通過(guò)該IBinder對(duì)象與Service進(jìn)行通訊了。

提示:

IBinder對(duì)象相當(dāng)于Service組件的內(nèi)部鉤子,該鉤子關(guān)聯(lián)到綁定的Service組件,當(dāng)其他程序組件綁定該Service時(shí),Service將會(huì)把IBinder對(duì)象返回給其他程序組件,其他程序組件通過(guò)該IBinder對(duì)象即可與Service組件進(jìn)行實(shí)時(shí)通訊。

實(shí)際上開(kāi)發(fā)時(shí)通常會(huì)采用繼承Binder(IBinder的實(shí)現(xiàn)類)的方式實(shí)現(xiàn)自己的IBinder對(duì)象。下面的程序示范了如何在Activity中綁定本地Service,并獲取Service的運(yùn)行狀態(tài)。該程序的Service類需要“真正”實(shí)現(xiàn)onBind()方法,并讓該方法返回一個(gè)有效的IBinder對(duì)象。該Service類的代碼如下。

上面Service類的粗體字代碼實(shí)現(xiàn)了onBind()方法,該方法返回了一個(gè)可訪問(wèn)該Service狀態(tài)數(shù)據(jù)(count值)的Binder對(duì)象,該對(duì)象被傳給該Service的訪問(wèn)者。

上面程序中的通過(guò)繼承Binder雷山縣了一個(gè)IBinder對(duì)象,這個(gè)MyBinder類是Service的內(nèi)部類,這對(duì)于本地綁定Service并與之通訊的場(chǎng)景的一種常見(jiàn)情形。

接下來(lái)定義一個(gè)Activity來(lái)綁定該Service,并在該Activity中通過(guò)MyBinder對(duì)象訪問(wèn)Service內(nèi)部狀態(tài)。該Activity的界面上包含三個(gè)按鈕,第一個(gè)按鈕用于綁定Service;第二個(gè)按鈕用于接觸綁定;第三個(gè)按鈕則用于獲取Service的運(yùn)行狀態(tài)。該Activity的代碼如下。

上面程序中

這段代碼用于在該Activity與Service鏈接成功時(shí)獲取Service的onBind()方法所返回的MyBinder對(duì)象;

這段代碼即可通過(guò)myBinder對(duì)象來(lái)訪問(wèn)Service的運(yùn)行狀態(tài)了。

運(yùn)行該程序,單擊程序界面中的綁定"Service"按鈕,即可看到Android Studio的logcat有如圖10.3所示的輸出。

在該Activity中綁定Service之后,該Activity還可通過(guò)MyBinder對(duì)象來(lái)獲取Service的運(yùn)行狀態(tài),如果用戶單擊程序界面上的"獲取Service狀態(tài)"按鈕,即可看到如圖10.4所示的輸出

圖 10.4

從圖10.4所示的輸出可以看到,該Activity可以非常方便地訪問(wèn)到Service的運(yùn)行狀態(tài)。雖然本程序只是一個(gè)簡(jiǎn)單的示例,該Activity只是訪問(wèn)了Service的一個(gè)簡(jiǎn)單count值,但實(shí)際上完全可以讓Mybinder去操作Service中更多的數(shù)據(jù)-----到底需要訪問(wèn)Service的多少數(shù)據(jù),完全取決于實(shí)際業(yè)務(wù)需要。

提示

對(duì)于Servicer的onBind()方法所返回的IBinder對(duì)象來(lái)說(shuō),它可以被當(dāng)成該Service組件所返回的代理對(duì)象,Service允許客戶端通過(guò)該IBinder對(duì)象來(lái)訪問(wèn)內(nèi)部的數(shù)據(jù),這樣即可實(shí)現(xiàn)客戶端與Service之間的通訊。

如果我們單擊程序界面上的"解除綁定"按鈕,即可在AS的logCat中看到如圖10.5所示輸出

圖10.5(解除綁定)

正如10.5中所示,當(dāng)程序調(diào)用unBindService()方法解除對(duì)某個(gè)Service的綁定時(shí),系統(tǒng)會(huì)先回調(diào)該Service的onUnbinde()方法,然后調(diào)用onDestry()方法。

與多次調(diào)用startService()方法啟動(dòng)Service()方法啟動(dòng)Service不同的是,多次調(diào)用bindService()方法并不會(huì)執(zhí)行重復(fù)綁定。對(duì)于前一個(gè)示例程序,用戶每單擊"啟動(dòng)"按鈕一次,系統(tǒng)就會(huì)回調(diào)Service的onStartCommand()方法一次;對(duì)于這個(gè)示例程序,不管用戶單擊"綁定Service”按鈕多少次,系統(tǒng)只會(huì)回調(diào)Service的onBiond()方法一次。

10.1.4 Service的生命周期

通過(guò)前面兩個(gè)示例,讀者應(yīng)該大致明白Service的生命周期了。隨著應(yīng)用程序啟動(dòng)Service方式不同,Service的生命周期也略有不同。

如果應(yīng)用程序通過(guò)startService()方法來(lái)啟動(dòng)Service,Service的生命周期如圖10.6左邊所示。如果應(yīng)用程序通過(guò)bindService方法來(lái)啟動(dòng)Service的生命周期如右圖所示:

Service的生命周期還有一個(gè)特殊的情形--------如果Service已由某個(gè)客戶端通過(guò)startService()方法啟動(dòng)了。接下來(lái)其他客戶端調(diào)用bindService()方法綁定該Service之后,再調(diào)用unbinService()方法解除綁定,最后有調(diào)用binService()方法再次綁定到Service,這個(gè)過(guò)程所觸發(fā)的生命周期方法如下所示onCreat()---- onStartCommand() ?---- onBind() ---- onUnbind()(重寫該方法時(shí)返回了true) ---- onRebind(),在上面這個(gè)觸發(fā)過(guò)程中,onCreat()是創(chuàng)建該Service后立即調(diào)用的,只有當(dāng)該service被創(chuàng)建時(shí)才會(huì)被調(diào)用;onStartCommand()方法則是有客戶端調(diào)用startService()方法時(shí)觸發(fā)的。圖10.7所示的logcat顯示了上面生命周期的輸出。

圖10.7

在圖10.7所示的輸出中,可以看到Service的onRebind()方法被回調(diào)了。如果希望該方法被回調(diào),除了需要該Service是由Activity的startService()方法啟動(dòng)之外,還需要Service子類重寫onUnbind()方法時(shí)返回true。

注意:

在圖10.7所示輸出中,并沒(méi)有發(fā)現(xiàn)Service回調(diào)onDestroy()方法,這是因?yàn)樵揝ervice并不是由Activity通過(guò)bindService()方法啟動(dòng)的(該Service事先已由Activity通過(guò)startActivity()方法啟動(dòng)了),因此當(dāng)Activity調(diào)用unBindService方法取消與該Service的綁定時(shí),該Service也不會(huì)終止。

10.1.5 使用IntentService

IntentService是Service的子類,因此它不是普通的Service,它比普通的Service增加了額外的功能。

先看Service本身存在的兩個(gè)問(wèn)題。

1、Service不會(huì)專門啟動(dòng)一個(gè)單獨(dú)的進(jìn)程,Service與它塑造應(yīng)用位于一個(gè)進(jìn)程中。

2、Service不是一條新的線程,因此不應(yīng)該在Service中直接處理耗時(shí)的任務(wù)。

提示:

如果開(kāi)發(fā)者需要在Service中處理耗時(shí)任務(wù),建議在Service中另外啟動(dòng)一條新的線程來(lái)處理該耗時(shí)任務(wù)。就像在前面BindService中所看到的,程序在BindService的onCreate()方法中啟動(dòng)了一條新線程來(lái)處理耗時(shí)任務(wù)。可能有讀者感到疑惑:直接在其他程序組件中啟動(dòng)子線程來(lái)處理耗時(shí)任務(wù)不行嗎?這種方式也不可靠,由于Activity可能會(huì)被用戶退出,而BraodcastReceiver的生命周期本身就很短??赡艹霈F(xiàn)的情況是:在子線程還沒(méi)結(jié)束的情況下,Activity已經(jīng)被用戶退出了,或者BroadcastReceiver已經(jīng)結(jié)束了。在Activity已經(jīng)退出、BroadcastReceiver已經(jīng)結(jié)束的情況下,此時(shí)他們所在的進(jìn)程就變成了空進(jìn)程(沒(méi)有任何活動(dòng)組件的進(jìn)程),系統(tǒng)需要內(nèi)存時(shí)可能會(huì)優(yōu)先終止該進(jìn)程,那么進(jìn)程內(nèi)的所有子線程也會(huì)被終止,這樣就可能導(dǎo)致子線程無(wú)法執(zhí)行完成。

而IntentService正好可以彌補(bǔ)Service的上述兩個(gè)不足:IntentService將會(huì)使用隊(duì)列來(lái)管理請(qǐng)求Intent,每當(dāng)客戶端代碼通過(guò)Intent請(qǐng)求啟動(dòng)IntentService時(shí),IntentServiec會(huì)將該Intent加入隊(duì)列中,然后開(kāi)啟一條新的worker線程來(lái)處理該IntentService。對(duì)于異步的startService()請(qǐng)求,IntentService會(huì)次序依次處理隊(duì)列中的Intent,該線程保證同一時(shí)刻只處理一個(gè)Intent。由于IntentService使用新的orker線程處理Intent請(qǐng)求,因此IntentService不會(huì)阻塞主線程,所以IntentService自己就可以處理耗時(shí)任務(wù)。

歸納起來(lái),IntentService具有如下特請(qǐng)求征:

1、IntentService會(huì)創(chuàng)建單獨(dú)的worker線程來(lái)處理所有的Intent請(qǐng)求

2、IntentService匯創(chuàng)建單獨(dú)的worker線程來(lái)處理onHandleIntent方法的實(shí)現(xiàn)代碼,因此開(kāi)發(fā)者無(wú)需處多線程的問(wèn)題。

3、當(dāng)所有請(qǐng)求處理完成后。IntentService會(huì)自動(dòng)停止,因此開(kāi)發(fā)者無(wú)須調(diào)用stopSelf()方法來(lái)停止該Service。

4、為Service的onBind()方法提供了默認(rèn)實(shí)現(xiàn),默認(rèn)實(shí)現(xiàn)的onBind()方法返回null。

5、為Service的onStartCommand()方法提供了默認(rèn)實(shí)現(xiàn),該實(shí)現(xiàn)將請(qǐng)求Intent添加到隊(duì)列中,

從上面的介紹可以看出,擴(kuò)展IntentService實(shí)現(xiàn)Service無(wú)須重寫onBind()、onStartCommand方法,只要重寫onHandleIntent()方法即可。

下面的示例程序界面中包含了兩個(gè)按鈕,分別用于啟動(dòng)普通Service和IntentService,兩個(gè)Service都需要處理耗時(shí)任務(wù)。該程序的界面布局代碼很簡(jiǎn)單,這里不再給出。主程序Activity代碼:

上面Activity的兩個(gè)事件處理方法中分別啟動(dòng)了MyService和MyIntentService,其中MyService是繼承service的子類,而MyIntentService則是繼承IntentService的子類。

下面是MyService類的代碼。

上面MySerevice在onStartCommand()方法中使用線程暫停的方式模擬了耗時(shí)任務(wù),該線程暫停了20秒,相當(dāng)于該耗時(shí)任務(wù)需要執(zhí)行20秒,由于普通Service的執(zhí)行會(huì)阻塞主線程,因此啟動(dòng)該線程將會(huì)導(dǎo)致程序出現(xiàn)ANR(Application Not Responding)異常。

下面是MyIntentService類的代碼

從上面的代碼可以看出,MyIntentService繼承了IntentService,并不需要實(shí)現(xiàn)onBind()、onStartCommand()方法,只要實(shí)現(xiàn)onHandleIntent()方法即可,在該方法中定義該Service需要完成的認(rèn)為誒。本示例的onHandleIntent()方法也用線程暫停的方式模擬了耗時(shí)任務(wù),線程同樣暫停了20秒。但由于IntentService會(huì)使用單獨(dú)的線程來(lái)完成該耗時(shí)任務(wù),因此啟動(dòng)MyIntentService不會(huì)阻塞前臺(tái)線程

運(yùn)行該示例,如果單擊界面上的“啟動(dòng)普通Service”按鈕,竟會(huì)激發(fā)startService()方法,該方法竟會(huì)啟動(dòng)MyService去執(zhí)行耗時(shí)任務(wù),此時(shí)將會(huì)導(dǎo)致程序UI線程被阻塞(程序界面失去響應(yīng)),而且由于阻塞時(shí)間太長(zhǎng),因此將會(huì)看到如圖10.8所示的ANR異常。

相反,如果調(diào)用“啟動(dòng)IntentService”來(lái)啟動(dòng)MyIntentService,雖然MyIntentService也需要執(zhí)行耗時(shí)任務(wù),但由于MyService會(huì)使用單獨(dú)的worker線程,因此MyIntentService不會(huì)阻塞前臺(tái)的UI線程,所以程序界面不會(huì)失去響應(yīng)。

10.2 電話管理器(TelephonyManager)

TelephonyManager是一個(gè)管理手機(jī)通話狀態(tài)、電話網(wǎng)絡(luò)的服務(wù)類,該類提供了大量的getXxx()方法來(lái)獲取電話網(wǎng)絡(luò)的相關(guān)信息。

在程序中獲取TelephonyManager十分簡(jiǎn)單,只要調(diào)用如下代碼即可:

接下來(lái)就可以通過(guò)TelephonyManager獲取相關(guān)信息或者進(jìn)行相關(guān)操作了。

實(shí)例:獲取網(wǎng)絡(luò)和SIM卡信息

通過(guò)TelephonyManager提供的一系列方法即可獲取手機(jī)網(wǎng)絡(luò)、SIM卡的相關(guān)信息,該程序使用了一個(gè)ListView來(lái)顯示網(wǎng)絡(luò)和SIM卡的相關(guān)信息。

該程序代碼如下:

由于該應(yīng)用需要獲取手機(jī)位置和手機(jī)狀態(tài),因此程序還需要在AndroidManifest.xml文件中增加如下配置:

10.3 短信管理器(SmsManager)

SmsManager是Android提供的的另一個(gè)非常常見(jiàn)的服務(wù),SmsManager提供了一系列sendXxxMessage()方法用于發(fā)送短信,不過(guò)就現(xiàn)在實(shí)際應(yīng)用來(lái)看,短信通常是普通的文本內(nèi)容,也就是調(diào)用sendTextMessage()方法進(jìn)行發(fā)送即可。

實(shí)例:發(fā)送短信

本實(shí)例程序十分簡(jiǎn)單,程序提供了文本框讓用戶輸入收件人號(hào)碼,一個(gè)文本框讓用戶輸入短信內(nèi)容,接下來(lái)單擊“發(fā)送”按鈕即可短信發(fā)送出去。

從上面程序可以看出,使用SmsManager發(fā)送短信十分簡(jiǎn)單,簡(jiǎn)單地調(diào)用sendTextMessage()方法即可發(fā)送短信。

上面程序中用到了一個(gè)PendingIntent對(duì)象,PendingIntent是對(duì)Intent的包裝,一般通過(guò)調(diào)用PendingIntent的getActivity()、getService()、getBroadcastReceiver()靜態(tài)方法來(lái)獲取PpendingIntent對(duì)象。與Intent對(duì)象不同的是,PendingIntent通?;貍鹘o其他應(yīng)用組件,從而有其他應(yīng)用程序來(lái)執(zhí)行PendingIntent所包裝的Intent。

該程序需要調(diào)用SMsManager來(lái)發(fā)送短信,因此還需要授予程序發(fā)送短信的權(quán)限,也就是在AndroidManifest.xml文件中增加如下代碼:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容