Android 面試題之四大組件相關

如何判斷當前BroadcastReceiver接受到的是有序廣播還是無序廣播

在BroadcastReceiver類中onReceiver()方法中,可以調用boolean b=isOrderedBroadcast();該方法是BroadcastReceiver類中提供的方法,用于高速我們當前的接收到的廣播是否為有序廣播

在manifest和代碼中如何注冊和使用BroadcastReceiver

在清單文件中注冊廣播接收者稱為靜態注冊,在代碼中注冊稱為動態注冊。

靜態注冊的廣播接收者只要app在系統中運行則一直可以接收到廣播消息,動態注冊的廣播接收者當注冊的Activity或者Service銷毀了那么就接收不到廣播了。

  • 靜態注冊:在清單文件中進行如下配置:
<receiver android:name=".BroadcastReceiver1" >
<intent-filter>
<action android:name="android.intent.action.CALL" >
</action>
</intent-filter>
</receiver>
  • 動態態注冊:在代碼中進行如下注冊
receiver = new BroadcastReceiver(); 
IntentFilter intentFilter = new IntentFilter(); 
intentFilter.addAction(CALL_ACTION); 
context.registerReceiver(receiver, intentFilter);

Service系列問題

Service本地服務及生命周期詳解

1.1 注冊Service需要注意什么

Service還是運行在主線程當中的,所以如果需要執行一些復雜的邏輯操作,最好在服務的內部手動創建子線程進行處理,否則會出現UI線程被阻塞的問題

1.2 Service與Activity怎么實現通信(不要死記硬背,結合文章)

相關文章

Service和Activity的相互通信

  • 方法一:

      1. 添加一個繼承Binder的內部類,并添加相應的邏輯方法
      1. 重寫Service的onBind方法,返回我們剛剛定義的那個內部類實例
      1. 重寫ServiceConnection,onServiceConnected時調用邏輯方法 綁定服務
  • 方法二

    • 通過接口Iservice調用Service方法,使用接口調用service和直接調用其實本質都是一樣的,只不過多了借口一個步驟

1.3 介紹源碼中Binder機制(了解)

面試問到這個,其實就是讓你說一下binder是干什么的,Service Manager是如何成為一個守護進程的

Binder機制

1.4 IntentService與Service的區別(intentservice的優點)

IntentService是Service的子類,是一個異步的,會自動停止的服務,很好解決了傳統的Service中處理完耗時操作忘記停止并銷毀Service的問題

  • 會創建獨立的worker線程來處理所有的Intent請求;
  • 會創建獨立的worker線程來處理onHandleIntent()方法實現的代碼,無需處理多線程問題;
  • 所有請求處理完成后,IntentService會自動停止,無需調用stopSelf()方法停止Service;
  • 為Service的onBind()提供默認實現,返回null;
  • 為Service的onStartCommand提供默認實現,將請求Intent添加到隊列中;
  • IntentService不會阻塞UI線程,而普通Serveice會導致ANR異常
  • Intentservice若未執行完成上一次的任務,將不會新開一個線程,是等待之前的任務完成后,再執行新的任務,等任務完成后再次調用stopSelf()

1.5 Service 是否在 main thread 中執行, service 里面是否 能執行耗時的操作?

默認情況,如果沒有顯示的指 service 所運行的進程, Service 和 activity 是運 行在當前 app 所在進程的 main thread(UI 主線程)里面。

service 里面不能執行耗時的操作(網絡請求,拷貝數據庫,大文件 )

特殊情況 ,可以在清單文件配置 service 執行所在的進程 ,讓 service 在另 外的進程中執行

<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" >
</service>

1.6 Service的生命周期

Service 有綁定模式和非綁定模式,以及這兩種模式的混合使用方式。不同 的使用方法生命周期方法也不同。

  • 非綁定模式:當第一次調用 startService 的時候執行的方法依次為 onCreate()、onStartCommand(),當 Service 關閉的時候調用 onDestory 方 法。

  • 綁定模式:第一次 bindService()的時候,執行的方法為 onCreate()、 onBind()解除綁定的時候會執行 onUnbind()、onDestory()。

上面的兩種生命周期是在相對單純的模式下的情形。我們在開發的過程中還 必須注意 Service 實例只會有一個,也就是說如果當前要啟動的 Service 已經存 在了那么就不會再次創建該 Service 當然也不會調用 onCreate()方法。

一個 Service 可以被多個客戶進行綁定,只有所有的綁定對象都執行了

onBind()方法后該 Service 才會銷毀,不過如果有一個客戶執行了 onStart() 方法,那么這個時候如果所有的 bind 客戶都執行了 unBind()該 Service 也不會 銷毀。

Service 的生命周期圖如下所示,幫助大家記憶。

只使用startService啟動服務的生命周期

只使用BindService綁定服務的生命周期

同時使用startService()啟動服務、BindService()綁定服務的生命周期

1.7 Activity、Intent、Service 是什么關系(了解)

他們都是 Android 開發中使用頻率最高的類。其中 Activity 和 Service 都是 Android 四大組件之一。他倆都是 Context 類的子類 ContextWrapper 的子類, 因此他倆可以算是兄弟關系吧。不過兄弟倆各有各自的本領,Activity 負責用戶 界面的顯示和交互,Service 負責后臺任務的處理。Activity 和 Service 之間可 以通過 Intent 傳遞數據,因此可以把 Intent 看作是通信使者。

1.8 Service 和 Activity 在同一個線程嗎?

對于同一 app 來說默認情況下是在同一個線程中的,main Thread (UI Thread)。

1.9 在 service 的生命周期方法 onstartConmand()可不可以執行網絡操作?如何在 service 中執行網絡操作?(在service如何執行耗時操作)

可以直接在 Service 中執行網絡操作,在 onStartCommand()方法中可以執行網絡操作

如果需要在服務中進行耗時操作,可以選擇IntentService, IntentService是Service的子類,用來處理異步請求。

IntentService在onCreate()方法中通過HandlerThread單獨開啟一個線程來處理Intent請求對象所對應的任務,這樣可以避免事務處理阻塞主線程。

onHandleIntent()函數針對Intent的不同進行不同的事務處理就可以,執行完一個Intent請求對象所對應的工作之后,如果沒有新的Intent請求達到,則自動停止Service; 否則ServiceHandler會取得下一個Intent請求
傳入該函數來處理其所對應的任務。

2.0 如何提高service的優先級? (理解,說出兩三條就很nB了)

參考文章

  • 1、在AndroidManifest.xml文件中對于intent-filter可以通過android:priority = “1000”這個屬性設置最高優先級,1000是最高值,如果數字越小則優先級越低,同時實用于廣播。

  • 2、在onStartCommand里面調用 startForeground()方法把Service提升為前臺進程級別,然后再onDestroy里面要記得調用stopForeground ()方法。

  • 3、onStartCommand方法,手動返回START_STICKY。

  • 4、 在onDestroy方法里發廣播重啟service。
    service +broadcast 方式,就是當service走ondestory的時候,發送一個自定義的廣播,當收到廣播的時候,重新啟動service。(第三方應用或是在setting里-應用-強制停止時,APP進程就直接被干掉了,onDestroy方法都進不來,所以無法保證會執行)

  • 5、監聽系統廣播判斷Service狀態。
    通過系統的一些廣播,比如:手機重啟、界面喚醒、應用狀態改變等等監聽并捕獲到,然后判斷我們的Service是否還存活。

  • 6、Application加上Persistent屬性。

2.1 Service 的 onStartCommand 方法有幾種返回值?各代表什么意思?

有四種返回值,不同值代表的意思如下:

  • START_STICKY:如果 service 進程被 kill 掉,保留 service 的狀態為開始狀態,但不保留遞送的 intent 對象。隨 后系統會嘗試重新創建 service,由于服務狀態為開始狀態,所以創建服務后一定會調用 onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啟動命令被傳遞到 service,那么參數 Intent 將為 null。
  • START_NOT_STICKY:“非粘性的”。使用這個返回值時,如果在執行完 onStartCommand 后,服務被異常 kill 掉,系統不會自動重啟該服務。
  • START_REDELIVER_INTENT:重傳 Intent。使用這個返回值時,如果在執行完 onStartCommand 后,服務被異 常 kill 掉,系統會自動重啟該服務,并將 Intent 的值傳入。
  • START_STICKY_COMPATIBILITY: START_STICKY 的兼容版本,但不保證服務被 kill 后一定能重啟。

2.2 Service 的 onRebind(Intent)方法在什么情況下會執行?

如果在 onUnbind()方法返回 true 的情況下會執行,否則不執行。

2.3 Activity 調用 Service 中的方法都有哪些方式?

  • Binder:
    通過 Binder 接口的形式實現,當 Activity 綁定 Service 成功的時候 Activity 會在 ServiceConnection 的類 的 onServiceConnected()回調方法中獲取到 Service 的 onBind()方法 return 過來的 Binder 的子類,然后通過對象調用方法。

  • Aidl:
    aidl 比較適合當客戶端和服務端不在同一個應用下的場景。

  • Messenger:
    它引用了一個Handler對象,以便others能夠向它發送消息(使用mMessenger.send(Message msg)方法)。該類允許跨進程間基于Message的通信(即兩個進程間可以通過Message進行通信),在服務端使用Handler創建一個Messenger,客戶端持有這個Messenger就可以與服務端通信了。一個Messeger不能同時雙向發送,兩個就就能雙向發送了

這里畫了一個粗淺的圖幫助大家理解。

image.png

1. Activity 系列問題

1.1 請簡要介紹Android的四大組件。(會說即可,不用死記硬背)

  • Activity:提供一個界面讓用戶點擊和各種滑動操作
  • Service :可以在后臺執行長時間運行操作而沒有用戶界面的應用組件
  • Broadcast Receiver :一種廣泛運用在應用程序之間傳輸信息的機制,通過發送Intent來傳送我們的數據
  • Content Provider :內容提供者,它是用在不同的應用程序之間共享數據時,可以把一個應用的數據提供給其他的應用使用。

1.2 Android中Activity, Intent, Content Provider, Service各有什么區別。(說出他們是什么即可)

  • Activity:
  • Intent: 意圖,描述應用想干什么。最重要的部分是動作和動作對應的數據。
  • Content Provider:
  • Service:

1.3 Manifest.xml文件中主要包括哪些信息?

  • 1.manifest:根節點,描述了package中所有的內容。
  • 2.uses-permission:請求你的package正常運作所需賦予的安全許可。
  • 3.permission: 聲明了安全許可來限制哪些程序能你package中的組件和功能。
  • 4.instrumentation:聲明了用來測試此package或其他package指令組件的代碼。
  • 5.application:包含package中application級別組件聲明的根節點。
  • 6.activity:Activity是用來與用戶交互的主要工具。
  • 7.receiver:IntentReceiver能使的application獲得數據的改變或者發生的操作,即使它當前不在運行。
  • 8.service:Service是能在后臺運行任意時間的組件。
  • 9.provider:ContentProvider是用來管理持久化數據并發布給其他應用程序使用的組件。

1.4 繪制Activity生命周期流程圖(Activity的生命周期)

1.4 介紹下不同場景下Activity生命周期的變化過程

  • 啟動Activity: onCreate()--->onStart()--->onResume(),Activity進入運行狀態。
  • Activity退居后臺: 當前Activity轉到新的Activity界面或按Home鍵回到主屏: onPause()--->onStop(),進入停滯狀態。
  • Activity返回前臺: onRestart()--->onStart()--->onResume(),再次回到運行狀態。
  • Activity退居后臺,且系統內存不足, 系統會殺死這個后臺狀態的Activity,若再次回到這個Activity,則會走onCreate()-->onStart()--->onResume()
  • 鎖定屏與解鎖屏幕 只會調用onPause(),而不會調用onStop方法,開屏后則調用onResume()

1.5 內存不足時系統會殺掉后臺的Activity,若需要進行一些臨時狀態的保存,在哪個方法進行?

Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它們不同于 onCreate()、onPause()等生命周期方法,它們并不一定會被觸發。

答:onSaveInstanceState() 方法,當應用遇到意外情況(如:內存不足、用戶直接按Home鍵)由系統銷毀一個Activity,onSaveInstanceState() 會被調用。但是當用戶主動去銷毀一個Activity時,例如在應用中按返回鍵,onSaveInstanceState()就不會被調用。除非該activity是被用戶主動銷毀的,通常onSaveInstanceState()只適合用于保存一些臨時性的狀態,而onPause()適合用于數據的持久化保存。

1.6 onSaveInstanceState()被執行的場景有哪些:

系統不知道你按下HOME后要運行多少其他的程序,自然也不知道activity A是否會被銷毀,因此系統都會調用onSaveInstanceState(),讓用戶有機會保存某些非永久性的數據。以下幾種情況的分析都遵循該原則

    1. 當用戶按下HOME鍵時
    1. 長按HOME鍵,選擇運行其他的程序時
    1. 鎖屏時
    1. 從activity A中啟動一個新的activity時
    1. 屏幕方向切換時

1.7 兩個 Activity 之間跳轉時必然會執行的是哪幾個方法?

一般情況下比如說有兩個 activity,分別叫 A,B,當在 A 里面激活 B 組件的時候, A 會調用 onPause()方法,然后 B 調用 onCreate() ,onStart(), onResume()。

這個時候 B 覆蓋了窗體, A 會調用 onStop()方法. 如果 B 是個透明的,或者 是對話框的樣式, 就不會調用 A 的 onStop()方法。

1.8 如何將一個 Activity 設置成窗口的樣式?

只需要給我們的 Activity 配置如下屬性即可。
android:theme="@android:style/Theme.Dialog"

1.9如何退出 Activity?如何安全退出已調用多個 Activity 的 Application?(知道即可)

  • 1.通常情況用戶退出一個 Activity 只需按返回鍵,我們寫代碼想退出 activity 直接調用 finish()方法就行。
  • 2.發送特定廣播:

在需要結束應用時,發送一個特定的廣播,每個 Activity 收到廣播后,關閉 即可。

//給某個 activity 注冊接受接受廣播的意圖 registerReceiver(receiver, filter)

//如果過接受到的是 關閉 activity 的廣播 activity finish()掉

  • 3.遞歸退出
    就調用 finish()方法 把當前的
    在打開新的 Activity 時使用 startActivityForResult,然后自己加標志,在 onActivityResult 中處理,遞歸關閉。
  • 4.其實 也可以通過 intent 的 flag 來實現 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)激活一個新的 activity。 此時如果該任務棧中已經有該 Activity,那么系統會把這個 Activity 上面的所有 Activity 干掉。其實相當于給 Activity 配置的啟動模式為 SingleTop。
  • 5.記錄打開的 Activity:
    每打開一個 Activity,就記錄下來。在需要退出時,關閉每一個 Activity
//偽代碼
List<Activity> lists ;// 在 application 全局的變量里面 lists = new ArrayList<Activity>();
lists.add(this);
for(Activity activity: lists)
{
       activity.finish();
    }
lists.remove(this); 

2.0 Android 中的 Context, Activity,Appliction 有什么區別?

  • 相同:Activity 和 Application 都是 Context 的子類。
    Context 從字面上理解就是上下文的意思,在實際應用中它也確實是起到了管理 上下文環境中各個參數和變量的總用,方便我們可以簡單的訪問到各種資源。
  • 不同:維護的生命周期不同。Context 維護的是當前的 Activity 的生命周期, Application 維護的是整個項目的生命周期。使用 context 的時候,小心內存泄露,防止內存泄露,注意一下幾個方面:

2.1 Context 是什么?(理解)

1、它描述的是一個應用程序環境的信息,即上下文。

2、該類是一個抽象(abstract class)類,Android 提供了該抽象類的具體實 現類(ContextIml)。

3、通過它我們可以獲取應用程序的資源和類,也包括一些應用級別操作, 例如:啟動一個 Activity,發送廣播,接受 Intent,信息,等。

附加一張Context繼承關系圖

這里寫圖片描述

2.2如何獲取當前屏幕Activity的對象?

使用ActivityLifecycleCallbacks

傳送地址:

Android 如何獲取當前Activity實例對象?

2.3你知道onNewIntent嗎?

如果IntentActivity處于任務棧的頂端,也就是說之前打開過的Activity,現在處于onPause、onStop 狀態的話,其他應用再發送Intent的話,執行順序為:
onNewIntent,onRestart,onStart,onResume。

2.4 除了用Intent 去啟動一個Activity,還有其他方法嗎?

使用adb shell am 命令

am啟動一個activity
adb shell am start com.example.fuchenxuan/.MainActivity
am發送一個廣播,使用action
adb shell am broadcast -a magcomm.action.TOUCH_LETTER

2.5 Android Service與Activity之間通信的幾種方式?

  • 通過Binder對象
    當Activity通過調用bindService(Intent service, ServiceConnection conn,int flags),得到一個Service的一個對象,通過這個對象我們可以直接訪問Service中的方法。
  • 通過Broadcast Receiver(廣播)的形式
  • EventBus

2.6 如果新Activity是透明主題時,舊Activity會不會走onStop

不會!

2.7 介紹Activity的幾中啟動模式,并簡單說說自己的理解或者使用場景

  • standard
    默認模式,可以不用寫配置。在這個模式下,都會默認創建一個新的實例。因此,在這種模式下,可以有多個相同的實例,也允許多個相同Activity疊加。

  • singleTop
    可以有多個實例,但是不允許多個相同Activity疊加。即,如果Activity在棧頂的時候,啟動相同的Activity,不會創建新的實例,而會調用其onNewIntent方法。

  • singleTask
    只有一個實例。在同一個應用程序中啟動他的時候,若Activity不存在,則會在當前task創建一個新的實例,若存在,則會把task中在其之上的其它Activity destory掉并調用它的onNewIntent方法。
    如果是在別的應用程序中啟動它,則會新建一個task,并在該task中啟動這個Activity,singleTask允許別的Activity與其在一個task中共存,也就是說,如果我在這個singleTask的實例中再打開新的Activity,這個新的Activity還是會在singleTask的實例的task中。

  • singleInstance
    只有一個實例,并且這個實例獨立運行在一個task中,這個task只有這個實例,不允許有別的Activity存在。

2.8 什么是ANR,如何避免他

image.png

2.9 Activity的管理機制

經驗總結
面試官問這個問題,想看看大家對Activity了解是否深入,什么是ActivityRecord,什么是TaskRecord,什么是ActivityManagerService,如果這些大家都能說出來,起碼是一個好多年工作經驗的老司機了,一般很多對Activity的了解還是停留在界面上

Activity的管理機制

簡述通過ContentResolver獲取ContentProvider內容的基本步驟

基本步驟:

得到ContentResolver類對象:ContentResolver cr = getContentResolver()。
定義要查詢的字段String數組。
使用cr.query();返回一個Cursor對象。
使用while循環得到Cursor里面的內容。

Android中如何訪問自定義ContentProvider?

通過ContentProvider的Uri訪問開放的數據。

  • 1.ContenResolver對象通過Context提供的方法getContenResolver()來獲得。
  • 2.ContenResolver提供了以下方法來操作:insert delete update query這些方法分別會調用ContenProvider中與之對應的方法并得到返回的結果。

SurfaceView和View的區別是什么?

SurfaceView中采用了雙緩存技術,在單獨的線程中更新界面;View在UI線程中更新界面

你在項目中哪些地方用到了XML?

XML的主要作用有兩個方面:數據交換和信息配置。在做數據交換時,XML將數據用標簽組裝成起來,然后壓縮打包加密后通過網絡傳送給接收者,接收解密與解壓縮后再從XML文件中還原相關信息進行處理,XML曾經是異構系統間交換數據的事實標準,但此項功能幾乎已經被JSON(JavaScript Object Notation)取而代之。當然,目前很多軟件仍然使用XML來存儲配置信息,我們在很多項目中通常也會將作為配置信息的硬代碼寫在XML文件中,Java的很多框架也是這么做的,而且這些框架都選擇了dom4j作為處理XML的工具,因為Sun公司的官方JavaSE實在不怎么好用。Android里的布局文件和配置文件都用的XML。

Android中定義style和theme的區別

經驗總結:

一般面試官問這樣

不同點:

  • Theme是應用于Activity或者是整個Application的,作用于單個Activity或者所有Acity,不能作用于某個控件的

  • Style是應用于某個(些)控件,Layout的,作用于控件級別的。

兩者總結一句就是:相對而言Theme是作用于全局的,而Style是作用于局部的。定義方式一樣,使用的地方不一樣。

相同點:

都位于values文件夾下的style.xml中,定義的方法一樣,都是控制UI的一堆屬性。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評論 6 540
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,275評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,368評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,736評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,919評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,481評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,235評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,427評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,656評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,160評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,380評論 2 379