全面解析:Android之Manifest.xml文件的标签+属性

引言

  作为Android开发人员,我们通常更多地关注业务逻辑代码的书写逻辑,但很少去关注Manifest.xml配置文件中的标签和属性,最近我就因为在写业务的时候,误漏了一个该文件中的配置,导致业务逻辑梳理的时候溜得飞起,而运行app却处处崩溃。
  年轻人要讲武德!淦,虽然调试花了整整一个下午,但确实通过这件事认识到了我的短板。闲话不多说,一起来学习吧!

Manifest.xml文件结构目录

<?xml version="1.0" encoding="utf-8"?>

<manifest>

    <uses-permission />
    <permission />
    <permission-tree />
    <permission-group />
    <instrumentation />
    <uses-sdk />
    <uses-configuration />  
    <uses-feature />  
    <supports-screens />  
    <compatible-screens />  
    <supports-gl-texture />  
    
    <application>
    
        <activity>
            <intent-filter>
                <action />
                <category />
                <data />
            </intent-filter>
            <meta-data />
        </activity>
    
        <activity-alias>
            <intent-filter> . . . </intent-filter>
            <meta-data />
        </activity-alias>
    
        <service>
            <intent-filter> . . . </intent-filter>
            <meta-data/>
        </service>
    
        <receiver>
            <intent-filter> . . . </intent-filter>
            <meta-data />
        </receiver>
    
        <provider>
            <grant-uri-permission />
            <meta-data />
            <path-permission />
        </provider>
    
        <uses-library />
    
    </application>

</manifest>

标签详细介绍

manifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            package="com.example.mydemo"
          android:sharedUserId="string"
          android:sharedUserLabel="string resource" 
          android:versionCode="integer"
          android:versionName="string"
          android:installLocation=["auto" | "internalOnly" | "preferExternal"] >
    . . .
</manifest>

(1)xmlns:android:定义android命名空间。
(2)package:定义app包名,每个app包名唯一。
(3)sharedUserId:具有相同的uderId并且具有相同签名的APP可以共享和访问彼此的数据,甚至可以在同一个进程里面运行,此时必须设置相同。
(4)sharedUserLabel:给共享userId定义了用户可读标签,只有设置了sharedUserId,此属性才有意义。
(5)versionCode:内部版本号。必须是整数,Integer类型。用来判断版本的升级,每一次发布都必须必之前的要大。如果versionName没有设置,则设置成此值。
(6)versionName:展示给用户看的版本号。为String类型。
(7)installLocation:设置apk文件的默认安装路径。

  • auto:系统优先安装apk包到内部存储,如果内部存储满了,则会安装到SD卡。

  • internalOnly:只能安装在设备ROM上(内部存储),ROM满了则弹出安装失败。

  • preferExternal,会优先安装在外部存储上(SD卡),当无SD卡或SD卡满了的话,则会安装到内部存储上。

  • uses-permission

<uses-permission  android:name="android.permission.WRITE_EXTERNAL_STORAGE"     
                                    android:maxSdkVersion="18" />

(1)name:权限的名称。可以是系统定义的权限,也可以是其他应用的权限,或者是使用自定义的权限。
(2)maxSdkVersion:此申请的权限最高的作用Android版本。

  • permission

自定义权限,以限制访问指定的组件或APP——本APP或其他APP,起到保护的作用。

  • permission-tree

声明一个权限树,可以在此节点上动态添加权限。

  • permission-group

声明一个逻辑上的权限分组。

  • instrumentation

声明一个Instrumentation类,用来监控APP和系统的交互。Instrumentation对象会在APP的所有组件之前进行实例化。

  • uses-sdk

指定app运行需要的sdk级别

  • uses-configuration

用来设置APP需要的相关硬件和软件的配置。大部分APP都不需要此属性。

  • uses-feature

用来声明APP所要使用和依赖的单一的软硬件功能。

  • supports-screens

  • compatible-screens

  • supports-gl-texture

  • application(重头戏来啦!!!)

<application android:allowTaskReparenting=["true" | "false"]
             android:allowBackup=["true" | "false"]
             android:allowClearUserData=["true" | "false"]
             android:backupAgent="string"
             android:backupInForeground=["true" | "false"]
             android:banner="drawable resource"
             android:debuggable=["true" | "false"]
             android:description="string resource"
             android:directBootAware=["true" | "false"]
             android:enabled=["true" | "false"]
             android:extractNativeLibs=["true" | "false"]
             android:fullBackupContent="string"
             android:fullBackupOnly=["true" | "false"]
             android:hasCode=["true" | "false"]
             android:hardwareAccelerated=["true" | "false"]
             android:icon="drawable resource"
             android:isGame=["true" | "false"]
             android:killAfterRestore=["true" | "false"]
             android:largeHeap=["true" | "false"]
             android:label="string resource"
             android:logo="drawable resource"
             android:manageSpaceActivity="string"
             android:name="string"
             android:networkSecurityConfig="xml resource"
             android:permission="string"
             android:persistent=["true" | "false"]
             android:process="string"
             android:restoreAnyVersion=["true" | "false"]
             android:requiredAccountType="string"
             android:resizeableActivity=["true" | "false"]
             android:restrictedAccountType="string"
             android:supportsRtl=["true" | "false"]
             android:taskAffinity="string"
             android:testOnly=["true" | "false"]
             android:theme="resource or theme"
             android:uiOptions=["none" | "splitActionBarWhenNarrow"]
             android:usesCleartextTraffic=["true" | "false"]
             android:vmSafeMode=["true" | "false"] >
    . . .
</application>

(1)name:Application子类(自定义Application)的全名。
(2)taskAffinity:指定APP中所有的Activity所属的任务栈的名字。
(3)allowTaskReparenting:如果此属性设置了true,表明允许某个ActivityX从打开它的那个任务栈移动到它本来所属的taskAffinity任务栈的最上面。
(4)allowBackup:是否允许使用adb backup和adb restore进行数据的备份和恢复。
(5)allowClearUserData:是否允许应用重置用户数据。
(6)backupAgent:用来设置备份代理。
(7)backupInForeground:在allowBackup设置为true的前提下,自动备份(Auto Backup)操作是否在APP运行在前台的时候进行数据备份。
(8)banner:用来轮播图。
(9)debuggable:是否允许APP进入调试模式。一般不设置此值,由编译器自动打包对其进行赋值。
(10)label:用户可读的此APP的标签。
(11)description:关于此APP的详细描述。
(12)directBootAware:Android7.0引入的新特性,是否可以可以在Direct Boot模式下运行。
(13)enabled:是否让系统对application中的组件进行实例化。
(14)extractNativeLibs:Android6.0引入的。安装APK包时是否对其中的.so文件提取出来。
(15)fullBackupContent:Android6.0引入。配合自动备份,用一个XML文件指明备份数据的规则。
(16)fullBackupOnly:当自动备份(Auto Backup)可以使用的时候的时候,是否开启。
(17)hasCode:APP是否包含代码。
(18)hardwareAccelerated:是否为所有的Activity和View进行硬件加速渲染。
(19)icon:APP的桌面显示的图标。
(20)isGame:是否游戏,用来和其他应用区分开来。
(21)killAfterRestore: 当系统恢复出厂设置,APP的设置信息被重置时,改APP是否应该被杀死。
(22)largeHeap:APP是否需要更大的内存空间。
(23)label:APP桌面显示的名称。如果不指定,则桌面名称为包名。
(24)logo:actionBar或toolBar上显示的图标。
(25)manageSpaceActivity:Activity子类的全名。
(26)networkSecurityConfig:指向XML配置文件,此XML配置文件为网络安全配置文件。
(27)permission:设置权限。
(28)persistent:是否让此APP持续地保持运行。
(29)process:设置进程名字。
(30)restoreAnyVersion:APP可以通过任何版本的备份数据进行数据恢复,即使是高版本备份的数据恢复到低版本中去。
(31)resizeableActivity:APP是否设置分屏操作。API24 引入。
(32)supportsRtl:是否支持从右到左布局。
(33)testOnly:设置此APP是否是用来测试的。
(34)theme:APP的主题。
(35)uiOptions:有none和splitActionBarWhenNarrow两项属性值。none为默认值。一般很少用到此项。
(36)usesCleartextTraffic:API23引入。是否允许网络使用明文传输。默认值为true。
(37)vmSafeMode:API22引入。是否让虚拟机运行在安全模式下。默认值为false。

  • activity

    对Activity的声明,APP中的所有APP必须在Manifest文件中声明才能够显示。

    <activity android:allowEmbedded=["true" | "false"]
              android:allowTaskReparenting=["true" | "false"]
              android:alwaysRetainTaskState=["true" | "false"]
              android:autoRemoveFromRecents=["true" | "false"]
              android:banner="drawable resource"
              android:clearTaskOnLaunch=["true" | "false"]
              android:colorMode=[ "hdr" | "wideColorGamut"]
              android:configChanges=["mcc", "mnc", "locale",
                                     "touchscreen", "keyboard", "keyboardHidden",
                                     "navigation", "screenLayout", "fontScale",
                                     "uiMode", "orientation", "density",
                                     "screenSize", "smallestScreenSize"]
              android:directBootAware=["true" | "false"]
              android:documentLaunchMode=["intoExisting" | "always" |
                                      "none" | "never"]
              android:enabled=["true" | "false"]
              android:excludeFromRecents=["true" | "false"]
              android:exported=["true" | "false"]
              android:finishOnTaskLaunch=["true" | "false"]
              android:hardwareAccelerated=["true" | "false"]
              android:icon="drawable resource"
              android:label="string resource"
              android:launchMode=["standard" | "singleTop" |
                                  "singleTask" | "singleInstance"]
              android:maxRecents="integer"
              android:maxAspectRatio="float"
              android:multiprocess=["true" | "false"]
              android:name="string"
              android:noHistory=["true" | "false"]  
              android:parentActivityName="string" 
              android:persistableMode=["persistRootOnly" | 
                                       "persistAcrossReboots" | "persistNever"]
              android:permission="string"
              android:process="string"
              android:relinquishTaskIdentity=["true" | "false"]
              android:resizeableActivity=["true" | "false"]
              android:screenOrientation=["unspecified" | "behind" |
    

    (1)name:Activity的子类全名。
    (2)allowEmbedded:此Activity是否可以作为其他Activity可嵌入的子Activity启动。在可穿戴的开发中此项需要设置为true。默认值为false。
    (3)taskAffinity:设置Activity所属任务栈的名称。
    (4)allowTaskReparenting:设置为true的时候:如果某个任务栈中的Activity启动了此Activity,则此Activity会移动到它本来所属的taskAffinity任务栈的最上面。
    (5)alwaysRetainTaskState:是否保持APP任务栈的状态。
    (6)autoRemoveFromRecents:当设置了此项的activity所启动的任务栈上的所有activity都关闭时,是否在预览屏幕(overview screen,其实也是最近人物列表)中移除。
    (7)clearTaskOnLaunch:当APP从桌面(Home Screen)切换回来是,是否移除掉任务栈上除了根Activity外的所有Activity,true为移除,false为不移除,默认值为false。此项只对根Activity起作用。
    (8)banner:在AndroidTV主页上的Activity进行轮播图片。
    (9)默认情况下当Activity的配置在运行时改变时,会被销毁掉并重启,此时一些信息会得不到保存,如输入框的信息,典型的例子就是横竖屏切换。配置此项的相关信息,可以避免配置改变带来的信息遗失,当设置的条件发生时,会触发Activity的onConfigurationChanged()回调方法。此项的值可以设置多种情况,用“|”分开。
    (10)directBootAware:Activity是否可以在锁屏的上运行和显示。
    (11)documentLaunchMode:Android 5.0添加。此项属性允许同一个APP能够有多个Activity展现在预览界面上(最近使用过的任务列表)。
    (12)enabled:Activity是否设置为系统进行实例化。默认值为true。
    (13)excludeFromRecents:以此Activity为根Activity的任务栈(task)是否从最近人物列表上移除,true为移除,false为包含。默认值为false。
    (14)exported:设置Activity是否可以被其他APP的组件启动。true可以;false不允许,不管是隐式调用还是显示调用。默认值为false。
    (15)finishOnTaskLaunch:当用户再次启动任务时(例如从预览界面切换),是否finish掉此Activity。默认值为false。当此项和allowTaskReparenting 同时设置为true时,会忽略掉allowTaskReparenting 属性。
    (16)hardwareAccelerated:开启硬件渲染加速。true为开启,false不开启。默认值为false。
    (17)icon:Activity的图标。作为任务栈的根Activity的icon可以在预览界面显示,并且会覆盖掉application的icon,也可以在intent-filter弹出的多选的activity显示icon。此项缺省的话和application设置的icon一样。
    (18)label:显示给用户看的Activity标签名。同icon显示的地方一样,一样会覆盖掉application的label。缺省的话和application设置的icon一样。
    (19)launchMode:Activity的四种启动模式。(standard |singleTop|singleTask|singleInstance)
    (20)maxRecents:以此Activity启动的任务栈(task)的最大数目,范围为1-50,默认值为16。超过数目会以最近最少使用的原则移除掉。
    (21)multiprocess:是否可以将Activity的实例启动到启动它的那个组件所属的进程中。true为允许,false为不允许。默认值为false。
    (22)noHistory:当Activity不可见时,是否将其从任务栈中移除并finish掉。true移除,activity不会留在任务栈内,所以此时onActivityResult()方法不会被调用。false不移除。默认为false。
    (23)parentActivityName:向上导航跳转到的Activity类名,必须要和目标Activity的name一致。
    (24)permission:对Activity设置权限保护。如果调用方未设置指定权限,则intent不会传递给Activity。
    (25)persistableMode:数据持久化。设置任务栈里的Activity在设备重启的时候是否进行数据的持久化处理。当设备重启后启动对应的Activity时能够对数据进行恢复。
    (26)process:设置运行此Activity的进程名字。
    (27)relinquishTaskIdentity:声明此属性的Activity是否放弃任务标识符而交由其任务栈上面的Activity。
    (28)resizeableActivity:是否支持多窗口展示。API 24引入
    (29)screenOrientation:Activity在设备的显示方向。如果是多屏显示,则会忽略此项。
    (30)stateNotNeeded:Activity在被kill掉的时候是否需要保存相关状态,在重启的时候是否需要回复状态。true不需要,此时在kill掉的时候不会调用onSaveInstanceState() 方法,onCreate()传null值,而不是Bundle。默认值为false。
    (31)supportsPictureInPicture:是否支持画中画。如果resizeableActivity设置为false则此项会被忽略掉。API 24引入。
    (32)theme:Activity的主题设置,如果此项缺省,则继承application的theme。
    (33)uiOptions:API 14引入。为Activity的UI添加额外的操作。
    (34)windowSoftInputMode:Activity 的主窗口与包含屏幕软键盘的窗口的交互方式。

  • activity-alias

    Activity的别名,为目标Activity提供快捷入口

    <activity-alias android:enabled=["true" | "false"]
                    android:exported=["true" | "false"]
                    android:icon="drawable resource"
                    android:label="string resource"
                    android:name="string"
                    android:permission="string"
                    android:targetActivity="string" > 
        . . .
    </activity-alias>
    

    (1)enabled:目标Activity是否可通过别名被系统实例化。默认为true。如果为false,则activity-alias无效。当application的enabled和此项都为true时,才能够对目标activity进行实例化。
    (2)exported:其他APP的组件是否可通过此别名来启动目标Activity。true为可以,false为不可以。如果为false,则只能由其所属的APP或相同User ID的APP启动。
    (3)icon:展示的图标。
    (4)label:展示的名字。
    (5)name:别名的唯一字符串名字,命名风格和Java类名全路径一样,必须唯一。
    (6)permission:通过别名启动目标Activity所需要的权限。
    (7)targetActivity:目标Activity在Manifest中声明的name。

  • meta-data

  以键值对的形式为其父级组件元素提供额外的数据,且其父组件可以包含任意多个meta-data元素。父组件元素包括:<application>、<activity>、<activity-alias>、<service>、<receiver>、<provider>。最终meta-data的值都会被封装到Bundle对象放到PackageItemInfo.metaData字段。

(1)name:meta-data的名字,必须具有唯一性。为了确保唯一性,最好用Java风格的规范命名。
(2)value:对应的值。
(3)resource:资源的引用,此处为资源的ID。

  • service

    声明一个服务组件。

    <service android:description="string resource"
             android:directBootAware=["true" | "false"]
             android:enabled=["true" | "false"]
             android:exported=["true" | "false"]
             android:icon="drawable resource"
             android:isolatedProcess=["true" | "false"]
             android:label="string resource"
             android:name="string"
             android:permission="string"
             android:process="string" >
        . . .
    </service>
    

    (1)description:对service做描述的字符串。
    (2)directBootAware:是否可以在锁屏的时候运行。默认值为false。
    (3)enabled:是否可被系统实例化。
    (4)exported:是否允许其他APP的组件对其进行调用或交互。
    (5)icon:service展示的图标。
    (6)isolatedProcess:如果设置为true,则此服务会运行在一个独立的进程中,此进程与系统的其他进程是分开的并且没有自己的权限。唯一能够与此服务通信的方法是通过服务的API。
    (7)label:展示给用户看的服务名字。不设置的话默认继承application的label。
    (8)name:服务子类全名。
    (9)permission:对service设置的权限保护。如果调用方未设置指定权限,则 startService(), bindService(), 或 stopService()不会起作用。如果此项未设置,则继承application的permission项,如果application也没设置,则Activity无权限。
    (10)process:服务运行所在的进程名,默认为APP运行所在的进程,与包同名。

  • receiver

    声明一个广播接收器(BroadcastReceiver的子类)组件。

    <receiver android:directBootAware=["true" | "false"]
              android:enabled=["true" | "false"]
              android:exported=["true" | "false"]
              android:icon="drawable resource"
              android:label="string resource"
              android:name="string"
              android:permission="string"
              android:process="string" >
        . . .
    </receiver>
    

    (1)directBootAware:是否可以在锁屏的时候运行。默认值为false。
    (2)enabled:是否可被系统实例化。默认为true。
    (3)exported:是否可接收其他APP发送的广播消息。
    (4)icon:展示的图标。
    (5)label:展示给用户看的名字
    (6)name:广播接收器子类的全名。
    (7)permission:设置保护权限。
    (8)process:广播接收器运行所在的进程名,默认为APP运行所在的进程,与包同名。

  • provider

    声明内容提供者(content provider)组件。

    <provider android:authorities="list"
              android:directBootAware=["true" | "false"]
              android:enabled=["true" | "false"]
              android:exported=["true" | "false"]
              android:grantUriPermissions=["true" | "false"]
              android:icon="drawable resource"
              android:initOrder="integer"
              android:label="string resource"
              android:multiprocess=["true" | "false"]
              android:name="string"
              android:permission="string"
              android:process="string"
              android:readPermission="string"
              android:syncable=["true" | "false"]
              android:writePermission="string" >
        . . .
    </provider>
    

    (1)name:ContentProvider对应的子类的全名。
    (2)authorities:指定提供给外部访问的URI标识,可以设置多个,用分号隔开。
    (3)enabled:是否可被系统实例化。
    (4)directBootAware:是否可以在锁屏的时候运行。
    (5)exported:是否可被其他APP访问。
    (6)icon:对应展示的图标。
    (7)initOrder:多个ContentProvider在同一个进程实例化的顺序,为整数值,大值会优先进行初始化。
    (8)label:展示给用户看的名字。
    (9)process:设置ContentProvider运行所在的进程名。
    (10)multiprocess:如果APP有多个进程在运行,则是否设置多个ContentProvider的实例,每个实例对应一个进程。
    (11)syncable:是否设置数据同步。
    (12)permission:连接此ContentProvider并进行读写操作所需的权限。
    (13)readPermission:设置客户端连接此ContentProvider进行读操作(查询)所需的权限。
    (14)writePermission:设置客户端连接此ContentProvider进行写操作(查询)所需的权限。
    (15)grantUriPermissions:是否可给平常无权对 Content Provider 数据的访问进行临时授权 ,使之能够对数据进行操作。

  • path-permission

    定义ContentProvider数据子集相关的路径和访问所需权限。

    <path-permission android:path="string"
                     android:pathPrefix="string"
                     android:pathPattern="string"
                     android:permission="string"
                     android:readPermission="string"
                     android:writePermission="string" />
    

    (1)path 用来匹配完整的路径,如:content://example.com/a/b/c,这里的path为“/a/b/c”。
    (2)pathPrefix 用来匹配路径的开头部分,拿上面的 Uri 来说,这里将 pathPrefix 的值为“/a”。
    (3)pathPattern:使用通配符的完整路径。
    (4)permission:设置访问所需的权限,读权限和写权限。
    (5)readPermission:读权限。
    (6)writePermissio:写权限。

  • uses-library

    定义APP必须链接的公共库, 本元素把程序包的类装载器中需要包含的库代码通知系统。

    <uses-library
      android:name="string"
      android:required=["true" | "false"] />
    

    (1)name:代码库的名字。
    (2)required:设置为true的话,如果系统没有name声明对应的库,则程序不能安装。设置为false,没有name声明对应的包也允许程序安装,单在APP里要做好对缺少声明库的相关处理。

大功告成!

参考文章

Android知识点回顾之Manifest文件——来自掘金的大神,知识点总结真的很到位。学习到了!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342