开发中遇到的一些操蛋问题

1. view.inflate 和 LayoutInflater 区别和联系

基本没区别,
view.inflate里边调用的是Layoutinflater,但是参数又不一样的地方,
view.inflate只能选择要不要挂载到父view只上,如果挂载那么layoutparms也随时设置,如果不载,layoutparms就不设置,
Layoutinflater多一个boolean参数可以自己设置,需要不需要设置layoutparms,
除了这点区别外,都一样用,基本可以不用考虑这点区别,一百年用不到一次.

2. TabLayout中的操蛋问题

tabMode 当条目超过屏幕宽度是,是否让他可以滚动,或者直接缩小填充
tabGravity 当条目不足屏幕宽度时,是否让他居中,或者直接扩大填充
这两个是配合着使用的,但是貌似又相互独立,TMD到时候自己看着办吧........

3.ListView始终定位底部

listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

4.web httpurlconnection接受客户端请求消息

  • 客户端代码
    如果使用urlconnection的话,传递参数,需要获取输出流,放入参数
    这是"post"请求,如果是"get",需要自己拼串了.
    OutputStream outputStream =httpURLConnection.getOutputStream();
    outputStream.write("type=download".getBytes());
    outputStream.flush();
  • 服务器代码
    需要使用servletoutputstream 来发送数据 ,用outputstream不可以,有问题,会导致数据不完整,不知道为啥

5.文件持久化存储的坑

  • 以下三个获取存储路径的方式,你可以忘得一干二净,因为你第三方应用只能读不能写,这些都系统的,看看就行了,想存自己的东西,没门儿......
    Environment---> getDataDirectory() getDownloadCacheDirectory() getRootDirectory ()
  • 想要存自己的东西,就用一下方式,对应两种,一个外置存储 一个内置存储,当app卸载是,他们也跟着卸载
    Context.getExternalFilesDir() Context.getFilesDir(); 放长时间保存的数据
    Context.getExternalCacheDir() Context.getCacheDir(); 放临时保存的数据
    因为有一对儿,不可能都用,所以在使用的时候要判断一下外置存储是否存在,然后选择用哪一个,存在就用外置,不存在,就用内置.
  • 如果要保存一些下载的内容,就不要放在以上目录下,就放到SD下就好.
    getExternalStorageDirectory()
    这个路径是根据手机设置来改变的,如果手机默认存储位置是内置,则指向的内置,如果默认存储是外置sd,则指向外置sd
    getExternalStoragePublicDirectory (String type) 这个是根据需要获取一个目录
    参数有DIRECTORY_MUSIC , DIRECTORY_PODCASTS, DIRECTORY_RINGTONES, DIRECTORY_ALARMS, DIRECTORY_NOTIFICATIONS, DIRECTORY_PICTURES,
    DIRECTORY_MOVIES, DIRECTORY_DOWNLOADS, DIRECTORY_DCIM
    到时候根据自己需要,去查吧....

6.简单的mxl布局优化

  • merge的使用

根布局,简单的FramLayout就用merge,
如果是自定义布局,根布局是Framlayout同上,如果是Linerlayout之类的,就要在自定义view中自己设定一下属性:
例如--> setOrientation(LinearLayout.HORIZONTAL);
注意事项: 在自定义布局中 使用merge ,inflate一个view时,要必须指定父布局,必须添加到父布局true
即---> inflate(int, ViewGroup, true)
不能在ViewStub中使用merge标签。最直观的一个原因就是ViewStub的inflate方法中根本没有attachToRoot的设置

作为根布局的merge,如果我们想设置自己设置背景什么的,可以这样
简要说明:因为Window窗体(比如Activity)加载时会自动添加PhoneWindow$DecorView和FrameLayout(id/content)两层布局
//setContentView(R.layout.layout_showset);
这个就不要了,我们自己去拿decorview然后拿到Framelayout,再找到我们的根布局,然后自己设置属性.
FrameLayout frameLayout = (FrameLayout)this.getWindow().getDecorView().findViewById(android.R.id.content);
frameLayout.setBackgroundResource(R.drawable.bg_repeated_main);
LayoutInflater.from(this).inflate(R.layout.layout_showset, frameLayout, true);

  • ViewStub的使用

简要说明:其实就是一个轻量级的页面,我们通常使用它来做预加载处理,来改善页面加载速度和提高流畅性,ViewStub本身不会占用层级,它最终会被它指定的层级取代。
给ViewStub设置资源,可以在xml中(android:layout="@layout/ layout_main"),也可以在代码中,如下:
mViewStub = (ViewStub)findViewById(R.id.viewstub);
mViewStub.setLayoutResource(R.layout.layout_main);

  • 注意事项:
    --> ViewStub只能Inflate一次,之后ViewStub对象会被置为空。按句话说,某个被ViewStub指定的布局被Inflate后,
    就不能够再通过ViewStub来控制它了。所以它不适用于需要按需显示隐藏的情况。
    --> ViewStub只能用来Inflate一个布局文件,而不是某个具体的View,
    当然也可以把View写在某个布局文件中。如果想操作一个具体的view,还是使用visibility属性吧。
    --> VIewStub中不能嵌套merge标签.
  • include的使用
    这个用来布局重用的,自己看着用吧,就不多说了......
    提醒一点:
    如果你给include设置了id,那么加入的布局里的跟布局,就不能设置了,否则会获取失败,报错崩溃.

7.Decimal 的使用

  • BigDecimal
    BigDecimal BigDecimal(double d); //不允许使用,精度不能保证,
    ---->这个构造方法 坑比较大,报各种异常,反正就是崩溃,千万别用
    BigDecimal BigDecimal(String s); //常用,推荐使用
    static BigDecimal valueOf(double d); //常用,推荐使用
  • DecimalFormat
    // 格式化:保留2为小数
    DecimalFormat df = new DecimalFormat("#.##");
    // 四舍五入,默认五舍六入
    df.setRoundingMode(RoundingMode.HALF_UP);
    例如 : new DecimalFormat( " 0.00"); 就是小数点后两位
符号 描述
0 如果不存在就显示0
# 如果不存在就不显示
. 分割符

8.自定义view的大坑逼

  • 系统帮我们测量的高度和宽度都是MATCH_PARNET,当我们设置明确的宽度和高度时,系统帮我们测量的结果就是我们设置的结果,当我们设置为WRAP_CONTENT,或者MATCH_PARENT系统帮我们测量的结果就是MATCH_PARENT的长度。
    所以,当设置了WRAP_CONTENT时,我们需要自己进行测量,即重写onMesure方法”:
    重写之前先了解MeasureSpec的specMode,一共三种类型:
    EXACTLY:一般是设置了明确的值或者是MATCH_PARENT
    AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT
    UNSPECIFIED:表示子布局想要多大就多大,很少使用
    所以当我们设置为warp_content时,尽量自己测量一下宽度,不然就是match_parent了
    代码例子如下:
    这是xml布局:
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.customview01.view.CustomTitleView  
      android:layout_width="wrap_content"  
      android:layout_height="wrap_content"  
      custom:titleText="3712"  
      android:padding="10dp"  
      custom:titleTextColor="#ff0000"  
      android:layout_centerInParent="true"  
      custom:titleTextSize="40sp" />  
    </RelativeLayout>  
    
    这是自定义view代码,测量宽高:
    @Override  
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  
    {  
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);  
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);  
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);  
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);  
        int width;  
        int height ;  
        if (widthMode == MeasureSpec.EXACTLY)  
    {  
      width = widthSize;  
    } else  
    {  
      mPaint.setTextSize(mTitleTextSize);  
      mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBounds);  
      float textWidth = mBounds.width();  
      int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());  
      width = desired;  
    }  
    
    if (heightMode == MeasureSpec.EXACTLY)  
      {  
      height = heightSize;  
     } else  
    {  
      mPaint.setTextSize(mTitleTextSize);  
      mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBounds);  
      float textHeight = mBounds.height();  
      int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());  
      height = desired;  
    }     
    setMeasuredDimension(width, height);  
    }  
    
  • 实例化view测量的问题
    先抛出我的问题:View rootView = View.inflate(this, R.layout.pop_layout, null);我实例化一个xml布局,但是我获取不到他的宽高,这个正常,以为没有设置lp,但是我设置了lp,也获取不到,这就是问题.
    解决方法:
    View rootView = View.inflate(this, R.layout.pop_layout, null);
    // rootView.measure(0,0); 在这里重新测量就好,也可以用下边的方法测量
    rootView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 这也是测量

    测量完跟布局大小后,还要测量一下子view的布局,
    rootView.layout(0, 0, rootView.getMeasuredWidth(), rootView.getMeasuredHeight());  
    
    我这里是要讲xml转化成一个bitmap,用了两种方式, 
    方式1:              
    rootView.setDrawingCacheEnabled(true);                
    rootView.buildDrawingCache();           
    Bitmap bitmap = rootView.getDrawingCache();
    方式2:             
    int width = rootView.getMeasuredWidth();   
    int height = rootView.getMeasuredHeight();
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    rootView.draw(canvas);           
    
    最后给imageview这是bitmap显示图片     
    image.setImageBitmap(bitmap);
    

9. Handler.post() 和 view.post()的区别

  • Handler.post(),需要自己创建Handler,view.post()内部默认已经能够帮我们获取了当前线程(即UI线程)的handler,然后又帮我们post到handler中,这里因为不像前一种方法new了一个新的线程,所以不要做复杂的逻辑计算,容易阻塞,但是简单的想偷个懒还是可以的.
    默认情况下,如果new Handler()的时候,没有传入某个线程的Looper对象(或传入null),系统就会默认绑定到创建Handler()对象的线程中。

10.service中弹toast的坑

  • 首先要明确一点就是: ** 所有更新UI的操作,都必须在UI线程中进行 **
    如果直接在service中弹toast,那么就会提示,handler没有初始化,或者looper不正确
    所以我们要创建一个handler,同事给其设置一个looper(这个looper是主线程的looper)
    代码如下:
    Handler handler = new Handler(getMainLooper()); //获取UIlooper
    handler.post(new Runnable() {
    @Override
    public void run() {
    Toast.makeText(getApplicationContext(), "wifi---->", Toast.LENGTH_SHORT).show();
    }});

11. MediaRecorder中的坑比事

  • 在设置录音功能时,顺需要对,也就是说,这是录音来源后,紧接着要设置录音输出的格式,再设置录音的编码格式

12. Dialog的背景风格

<style name="ModalDialog" parent="@android:style/Theme.Dialog">   
     <item name="android:windowFrame">@null</item>    <!-- 设置窗体边框 -->   
     <item name="android:windowIsFloating">true</item>    <!-- 窗体是否浮现在activity之上 -->                                          
     <item name="android:windowIsTranslucent">false</item>    <!-- 窗体是否半透明 -->    
     <item name="android:windowFullscreen">true</item>    <!-- 窗体是否全屏 -->
     <item name="android:windowNoTitle">true</item>    <!-- 窗体有无标题-->
     <item name="android:background">@null</item>    <!-- 背景 -->
     <item name="android:windowBackground">@android:color/transparent</item>    <!-- window背景 -->
     <item name="android:backgroundDimEnabled">false</item>    <!-- 背景是否模糊显示 -->
     <item name="android:windowContentOverlay">@null</item>     <!-- 窗体内容背景 -->
     <item name="windowOverscan">false</item>          <!-- 是否要求窗体铺满整屏幕-->
</style> 

13. 通过api拿到资源id

方法1:
int id = Context.getResources().getIdentifier("activity_main","layout",paramContext.getPackageName());
方法2:
Field field = R.id.class.getField("edit2");
int id = field.getInt("edit2");

14. 权重weight

当设置了wrap_content时,权重,最小要能包裹能容,也就是说即使权重小,但是也要先放下全部内容,所以大小还是会变

当设置了fill_parent(match_parent)时,权重,最大只能是填充父窗体,也就是说,就算内容再多,也只能到父窗体那么大
如果设置为0dp,那就是严格按照权重比例来区分了

15.path颜色设置问题

1 .在我做自定义画板view的时候,需要重新给画笔设置颜色,但是颜色会覆盖之前已经画好的东西,问题就是,如果 要改变颜色,就要重新new 一个新的path出来,总之每次的都不能一样,可以保存起来,颜色一样的再复用.

2 . 另外paint画笔的设置,风格很重要,,一个是fill 填充,一个是stroke描边这个要区别开

16.Dagger2中的问题

dagger是针对类与类之间调用,导致耦合性提高,而提供通过依赖注入的方式解耦的一个框架.(我不喜欢用)

module : 用来告知dagger 该依赖(要注入的对象) 的构造方法,这里需要注意的问题是,如果构造方法有多个参数,那么需要一层一层的去通过@provides 来告知,不可以一次性告知,例如:

//这是需要注入对象的构造方法
 @Injectpublic LoginPresenter(ILoginActivity iLoginActivity, IM im) {  
          this.iLoginActivity = iLoginActivity;    this.im = im;
  }
          
 //这是module告知的方式
  private final ILoginActivity iLoginActivity;
  public LoginActivityModule(ILoginActivity iLoginActivity) {
        this.iLoginActivity = iLoginActivity;
  }
  @Provides
  ILoginActivity provideIloginActivity() {
        return iLoginActivity;
  }
  @Provides
  LoginPresenter provideLoginPresenter(ILoginActivity iLoginActivity, IM im) {
         return new LoginPresenter(iLoginActivity, im);
  }
  1. dagger中module 和 component的工作流程是,component负责连接 宿主依赖 ,当 宿主 中注入 依赖 时,dagger就会从 宿主 注册的component中寻找 依赖被注册的 构造法方法,然后进行实例化,最后就完成了注入
  1. 对于在Component中添加 dependencies 依赖,这样的话,本个Component会继承dependencies里的所有实例化对象,这种情况一般用在继承AppComponent,而AppComponent则实例化了一些全局性的变量
  2. 而对于Component中的 modules参数,里边则是告知dagger,需要实例化哪些类,对应的module中要给出构造函数的实例化方法

17.java文件路径问题

在写一个客户端通过URL地址下载服务器图片的额时候,怎么都加载不出来图片,后来发现,原来忘了写 http:// ,当时想省事直接从ip地址开始写的.
另外,发现一个好玩的东西,java服务器只需要把图片放到项目的webcontent目录下,即可,例如我在 webcontent 目录下,新建了一个image文件夹,把所有的图片都放进去了,然后我客户端的路径就可以这样写:

    path = "http://123.56.104.149:8080/DrawingAndGuessingServer/image/1.jpg";
    Glide.with(this).load(new URL(path)).into(image);   这里用的glide图片加载框架

这样,直接就把图片加载到imageview中了,,而不是我之前想的那样还要写什么输入流输出流,唉:-(,,TMD,想多了.,原来这么简单!

18.项目中AppTheme报错问题

No resource found that matches the given name 'Theme.AppCompat.Light'.

查看 res/values/styles.xml 下的报错点。
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
把这个改成

<style name="AppBaseTheme" parent="android:Theme.Light">

路径: res/values-11/styles.xml
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
把这个改成
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">

路径: res/values-14/styles.xml
<style name="AppBaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
把这个换成
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">

19.Dialog中dismiss和hide的区别

dismiss和hide方法都可以隐藏对话框,在需要的时候也可以用show方法调用显示。但是,这两者是有区别的。
dismiss方法会释放对话框所占的资源,而hide方法不会。activity退出前必须调用dismiss方法关闭对话框。
如果对话框上有progressbar,你会发现,调用dismiss方法后,再调用show方法,出来的对话框,上面的progressbar不再会转动,而调用hide方法的则没有问题。
所以,最正确的调用方法是,在activity的onDestory方法里调用dismiss方法,其他地方都用hide方法隐藏对话框。

20.app退出后台,重新进入后,页面重新载入问题

问题具体描述: 打开app,进入一个页面,然后点击home,退到后台,这时候,再次点击app图标进入app,应该打开上次的页面,而不是重新载入.
问题解决: 我的app入口是,splashactivity,,我把splashactivity的启动模式设置成singleTask了,,所以导致每次点击app图标进入,会重新载入,其实不是重新载入了,而是重新走splashactivity了,如果我们有这个需求,可以这样写,每次点击app图标,就会重新走这里,,如果没有,想点击app图标,回到上次的页面,我们就把启动模式换掉就可以了.

21.app异常强制退出后,自动重启问题

在自己的Activity堆栈管理类中,finish掉虽有的activity就可以了
没有试过,他妈因为测不出来bug了,反正就是好了

22.微信分享,不显示缩略图bug

是因为分享的简介中存在 微信认为的 敏感词汇:元 红包 领取,目前知道的就这几个,也许有别的,微信也没有文档,自己看着办吧.

23.android图标文件夹 规范(原则是不低于规范尺寸,单位:px)

hdpi文件夹 —— 192x192

xhdpi文件夹 —— 256x256

xxhdpi文件夹 —— 384x384

xxxhdpi文件夹 —— 512x512

注:分辨率适配目录参考

480*800 drawable-hdpi

540*960 drawable-sw360dp-hdpi

720*1280 drawable-sw360dp-xhdpi

1080*1920 drawable-sw360dp-xxhdpi

1440*2560 drawable-sw360dp-xxxhdpi

24.activity设置了竖屏,拍照回来,仍然出现横屏导致冲走oncreate()

什么原因导致的目前不清楚,目前就是找到了解决方案。在清单文件对应
activity里,配置一下android:configChanges="orientation|screenSize|keyboardHidden"这个属性,让activity横竖屏或者而其他意外原因导致重建时,不走oncreate,而是走谷歌提供出的onConfigurationChanged方法,详情见https://www.jianshu.com/p/ae0297fcc231

25. 设置 Textview 超过高度,可滚动

  textView.setMovementMethod(ScrollingMovementMethod.getInstance());

26. invalidate , requestLayout , requestFocus , layout

  - invalidate  请求重绘View树,即draw过程,不会触发onMeasure
  - requestLayout  只调用measure和layout过程,不会调用draw
  - requestFocus   获取焦点的会导致view的重绘
  - layout  对控件进行重新定位执行onLayout()

27. TextView getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG)失效

原因不清楚,网上有人说是因为字体小于12sp导致,但我的字体是13sp

    解决方法 :  第一步 TextView设置paddingBottom='1dp'
                第二步 文案在代码中通过 setText() 设置,不要在xml布局中设置

28. 补间动画Animation 设置循环setRepeatCount(Animation.INFINITE)失效

    设置补间动画,要不在xml中把所有属性定义完,要不就完全代码写。
    如果在xml中定义动画,在java中定义重复模式,重复次数,那么重复的效果就失效

28. AndroidStudio preview一直不显示布局

    在build.gradle 中没有配置  buildToolsVersion

29. 输入框 明文密文切换

    ivEyes.setOnClickListener(v -> {
        if (ivEyes.isSelected()) {
            ivEyes.setSelected(false);
    //      etSecret.setInputType(InputType.TYPE_CLASS_TEXT |     InputType.TYPE_TEXT_VARIATION_PASSWORD);                     etContent.setTransformationMethod(PasswordTransformationMethod.getInstance());
            etContent.setSelection(etContent.getText().length());
        } else {
            ivEyes.setSelected(true);
    //      etSecret.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
            etContent.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
            etContent.setSelection(etContent.getText().length());
        }
    });

29.蒙层点击事件透传到底层

  给蒙层根布局设置 android:clickable="true"

一大波坑即将来袭,持续更新中.......

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

推荐阅读更多精彩内容