webview 開發(fā)常用點(diǎn)介紹

1.基本適配設(shè)置

settings =getSettings();
settings.setJavaScriptEnabled(true);//支持js
settings.setUseWideViewPort(true); 
settings.setLoadWithOverviewMode(true);

2.硬件加速 提高webview加載速度

if (Build.VERSION.SDK_INT >= 21) {
    settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
    setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else if (Build.VERSION.SDK_INT >= 19) {
    setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else if (Build.VERSION.SDK_INT < 19) {
    setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

3.設(shè)置webview 安全性 一般上傳應(yīng)用會(huì)對(duì)apk進(jìn)行安全掃描霎烙,有關(guān)webview的安全問題遣耍,可通過(guò)該方法解決

private void setWebViewSecurity(){
    try {
        removeJavascriptInterface("searchBoxJavaBridge_");
        removeJavascriptInterface("accessibility");
        removeJavascriptInterface("accessibilityTraversal");   
        getSettings().setSavePassword(false);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
      } catch (Exception e) {
    }
}

4.支持視頻全屏播放方法滋戳,重寫webChromeClient getVideoLoadingProgressView,onShowCustomView,onHideCustomView
三個(gè)方法。
原理是獲取視頻播放的view 然后創(chuàng)建父類容器view 加載到根view上顯示出來(lái)

 public class CommonWebChromeClient extends WebChromeClient{
 /*** 視頻播放相關(guān)的方法 **/
        @Override
        public View getVideoLoadingProgressView() {
            if(videoWebFactory!=null){
                return videoWebFactory.getVideoLoadingProgressView();
            }
            return null;
        }
        @Override
        public void onShowCustomView(View view, CustomViewCallback callback) {
            if(videoWebFactory!=null){
                videoWebFactory.showCustomView(view, callback);
            }
        }
        @Override
        public void onHideCustomView() {
            if(videoWebFactory!=null){
                videoWebFactory.hideCustomView();
            }
        }
}

VideoWebFactory代碼

public class VideoWebFactory {
      /** 視頻全屏參數(shù) */
    protected static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    private View customView;
    private FrameLayout fullscreenContainer;
    private WebChromeClient.CustomViewCallback customViewCallback;
    private Context context;
    private Window window;
    private WebView webView;
 
    public  VideoWebFactory (Context context,WebView webView){
        this.context =context;
        this.window =  ((Activity)context).getWindow();
        this.webView = webView;
    }
    public View getVideoLoadingProgressView(){
        FrameLayout frameLayout = new FrameLayout(context);
        frameLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        return frameLayout;
    }
    /** 視頻播放全屏 **/
    public void showCustomView(View view, CustomViewCallback callback) {
        // if a view already exists then immediately terminate the new one
        if (customView != null) {
            callback.onCustomViewHidden();
            return;
        }
       window.getDecorView();
        FrameLayout decor = (FrameLayout) window.getDecorView();
        fullscreenContainer = new FullscreenHolder(context);
        fullscreenContainer.addView(view, COVER_SCREEN_PARAMS);
        decor.addView(fullscreenContainer, COVER_SCREEN_PARAMS);
        customView = view;
        setStatusBarVisibility(false);
        customViewCallback = callback;
    }
    
    /** 隱藏視頻全屏 */
    public void hideCustomView() {
        if (customView == null) {
            return;
        }
        setStatusBarVisibility(true);
        FrameLayout decor = (FrameLayout) window.getDecorView();
        decor.removeView(fullscreenContainer);
        fullscreenContainer = null;
        customView = null;
        customViewCallback.onCustomViewHidden();
        webView.setVisibility(View.VISIBLE);
    }
    /** 全屏容器界面 */
   private static class FullscreenHolder extends FrameLayout {

        public FullscreenHolder(Context ctx) {
            super(ctx);
            setBackgroundColor(ctx.getResources().getColor(android.R.color.black));
        }
        @Override
        public boolean onTouchEvent(MotionEvent evt) {
            return true;
        }
    }
    private void setStatusBarVisibility(boolean visible) {
        int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
        window.setFlags(flag, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }
    public View getCustomView() {
        return customView;
    }
}

4.支持文件上傳
webview支持file文件上傳佛致,不過(guò)讶凉,對(duì)應(yīng)有版本的區(qū)別,5.0以下的版本只能每次選擇一個(gè)文件瘫辩,5.0以上的版本支持多文件選擇
(1)當(dāng)觸發(fā)上傳文件選擇的時(shí)候伏嗜,webview會(huì)回調(diào)openFileChooser 方法并提供ValueCallback<Uri> mUM 作為文件上傳提交對(duì)象(文件選擇可以調(diào)用相關(guān)的庫(kù))
(2)最后在選擇完文件之后,設(shè)置uri 對(duì)象伐厌,通過(guò)mUM.onReceiveValue(uri);進(jìn)行文件提交承绸。注意,如果沒有選擇文件挣轨,請(qǐng)?jiān)O(shè)置mUM.onReceiveValue(null); 作為取消選擇文件的操作军熏,不然,webview將處于文件選擇狀態(tài)卷扮,web頁(yè)面不能點(diǎn)擊響應(yīng)荡澎。

 public class CommonWebChromeClient extends WebChromeClient{
/**
         * 文件上傳
         * */
        //For Android 3.0+
        public void openFileChooser(ValueCallback<Uri> uploadMsg){
            mUM = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("*/*");
            ((Activity)context).startActivityForResult(Intent.createChooser(i,"File Chooser"), WebFileFactory.SELECT_PHOTO);
        }
        // For Android 3.0+, above method not supported in some android 3+ versions, in such case we use this
        public void openFileChooser(ValueCallback uploadMsg, String acceptType){
            mUM = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("*/*");
            ((Activity)context).startActivityForResult(Intent.createChooser(i, "File Browser"),WebFileFactory.SELECT_PHOTO);
        }
        //For Android 4.1+ 只能選擇一個(gè)文件
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
            mUM = uploadMsg;
            if(onFileSelected!=null){
                onFileSelected.onSelectOne(mUM,mUMA);
            }
            if(webFileFactory!=null){
                webFileFactory.setmUM(mUM);
                webFileFactory.showPhotoSelectForOne();
            }
        }
       //For Android 5.0+ 多個(gè)文件選擇
        public boolean onShowFileChooser(
                WebView webView, ValueCallback<Uri[]> filePathCallback,
                WebChromeClient.FileChooserParams fileChooserParams){
            mUMA = filePathCallback;
            if(onFileSelected!=null){
                onFileSelected.onSelect(mUM,mUMA);
            }
            if(webFileFactory!=null){
                webFileFactory.setmUMA(mUMA);
                webFileFactory.showPhotoSelect();
            }
            return true;
}

webFileFactory為 圖片選擇 處理類

public class WebFileFactory {
    private Context context;
    private ValueCallback<Uri> mUM;
    private ValueCallback<Uri[]> mUMA;
    private Uri uri;
    public static final int TAKE_PICTURE = 102;
    public static final int SELECT_PHOTO = 103;
    public static final int TAKE_VIDEO = 107;
    public static final int SELECT_VIDEO = 106;
    public static final int TAKE_PICTURE_ONE = 104;
    public static final int SELECT_PHOTO_ONE = 105;
    public static final int TAKE_VIDEO_ONE = 108;
    public static final int SELECT_VIDEO_ONE = 109;

    public WebFileFactory(Context context) {
        this.context = context;
    }

    public void setmUM(ValueCallback<Uri> mUM) {
        this.mUM = mUM;
    }

    public void setmUMA(ValueCallback<Uri[]> mUMA) {
        this.mUMA = mUMA;
    }

    public void showPhotoSelectForOne() {
        String[] datas = new String[] { "拍照", "錄像", "相冊(cè)", "視頻" };
        SheetView sheetView = new SheetView(context, datas);
        sheetView.setLisenter(new SheetView.Lisenter() {
            @Override
            public void onSelect(int position) {
                if (position == 1) {
                    uri = Uri.fromFile(new File(
                            FileUtils.getAppImageFilePath(context) + "/" + System.currentTimeMillis() + ".png"));
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
                    intent.putExtra("return-data", true);
                    ((Activity) context).startActivityForResult(intent, WebFileFactory.TAKE_PICTURE_ONE);
                } else if (position == 2) {
                    uri = Uri.fromFile(new File(
                            FileUtils.getAppImageFilePath(context) + "/" + System.currentTimeMillis() + ".mp4"));
                    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);// 創(chuàng)建一個(gè)請(qǐng)求視頻的意圖
                    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);// 設(shè)置視頻的質(zhì)量,值為0-1画饥,
                    intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 60);// 設(shè)置視頻的錄制長(zhǎng)度衔瓮,s為單位
                    intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 20 * 1024 * 1024L);// 設(shè)置視頻文件大小浊猾,字節(jié)為單位
                    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
                    ((Activity) context).startActivityForResult(intent, WebFileFactory.TAKE_VIDEO_ONE);
                } else if (position == 3) {
                    Intent intent = new Intent(context, SelectPhotoActivity.class);
                    intent.putExtra("max", 1);
                    ((Activity) context).startActivityForResult(intent, WebFileFactory.SELECT_PHOTO_ONE);
                } else if (position == 4) {
                    Intent i = new Intent(Intent.ACTION_PICK,
                            android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
                    ((Activity) context).startActivityForResult(i, WebFileFactory.SELECT_VIDEO_ONE);
                }
            }
        });
        sheetView.show();
    }

    public void showPhotoSelect() {
        String[] datas = new String[] { "拍照", "錄像", "相冊(cè)", "視頻" };
        SheetView sheetView = new SheetView(context, datas);
        sheetView.setLisenter(new SheetView.Lisenter() {
            @Override
            public void onSelect(int position) {
                if (position == 1) {
                    uri = Uri.fromFile(new File(
                            FileUtils.getAppImageFilePath(context) + "/" + System.currentTimeMillis() + ".png"));
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
                    intent.putExtra("return-data", true);
                    ((Activity) context).startActivityForResult(intent, WebFileFactory.TAKE_PICTURE);
                } else if (position == 2) {
                    uri = Uri.fromFile(new File(
                            FileUtils.getAppImageFilePath(context) + "/" + System.currentTimeMillis() + ".mp4"));
                    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);// 創(chuàng)建一個(gè)請(qǐng)求視頻的意圖
                    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);// 設(shè)置視頻的質(zhì)量抖甘,值為0-1,
                    intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 60);// 設(shè)置視頻的錄制長(zhǎng)度葫慎,s為單位
                    intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 20 * 1024 * 1024L);// 設(shè)置視頻文件大小衔彻,字節(jié)為單位
                    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
                    ((Activity) context).startActivityForResult(intent, WebFileFactory.TAKE_VIDEO);
                } else if (position == 3) {
                    Intent intent = new Intent(context, SelectPhotoActivity.class);
                    intent.putExtra("max", 9);
                    ((Activity) context).startActivityForResult(intent, WebFileFactory.SELECT_PHOTO);
                } else if (position == 4) {
                    Intent i = new Intent(Intent.ACTION_PICK,
                            android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
                    ((Activity) context).startActivityForResult(i, WebFileFactory.SELECT_VIDEO);
                } else {
                    if (mUMA != null) {
                        mUMA.onReceiveValue(null);
                    } else if (mUM != null) {
                        mUM.onReceiveValue(null);
                    }
                }
            }
        });
        sheetView.show();
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == TAKE_PICTURE_ONE || requestCode == TAKE_VIDEO_ONE) {
            if (uri != null) {
                mUM.onReceiveValue(uri);
            }
        } else if (requestCode == SELECT_PHOTO_ONE) {
            if (data != null) {
                Bundle bundle = data.getBundleExtra("bundle");
                List<PhotoInfo> imgs = bundle.getParcelableArrayList("imgs");
                Uri uri = Uri.parse(imgs.get(0).getPath_file());
                mUM.onReceiveValue(uri);
            } else {
                if (mUMA != null) {
                    mUMA.onReceiveValue(null);
                } else if (mUM != null) {
                    mUM.onReceiveValue(null);
                }
            }
        } else if (requestCode == SELECT_VIDEO_ONE) {
            if (data != null) {
                Uri uri = data.getData();
                Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
                cursor.moveToFirst();
                String path = "file://" + cursor.getString(1); // 視頻文件路徑
                Uri uri_video = Uri.parse(path);
                mUM.onReceiveValue(uri_video);
            } else {
                if (mUMA != null) {
                    mUMA.onReceiveValue(null);
                } else if (mUM != null) {
                    mUM.onReceiveValue(null);
                }
            }
        }

        if (requestCode == TAKE_PICTURE || requestCode == TAKE_VIDEO) {
            if (uri != null) {
                Uri[] uris = new Uri[] { uri };
                mUMA.onReceiveValue(uris);
            }
        } else if (requestCode == SELECT_PHOTO) {
            if (data != null) {
                Bundle bundle = data.getBundleExtra("bundle");
                List<PhotoInfo> imgs = bundle.getParcelableArrayList("imgs");
                Uri[] uris = new Uri[imgs.size()];
                for (int i = 0; i < imgs.size(); i++) {
                    PhotoInfo photoInfo = imgs.get(i);
                    Uri uri = Uri.parse(photoInfo.getPath_file());
                    uris[i] = uri;
                }
                mUMA.onReceiveValue(uris);
            } else {
                if (mUMA != null) {
                    mUMA.onReceiveValue(null);
                } else if (mUM != null) {
                    mUM.onReceiveValue(null);
                }
            }
        } else if (requestCode == SELECT_VIDEO) {
            if (data != null) {
                Uri uri = data.getData();
                Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
                cursor.moveToFirst();
                String path = "file://" + cursor.getString(1); // 視頻文件路徑
                Uri uri_video = Uri.parse(path);
                mUMA.onReceiveValue(new Uri[] { uri_video });
            } else {
                if (mUMA != null) {
                    mUMA.onReceiveValue(null);
                } else if (mUM != null) {
                    mUM.onReceiveValue(null);
                }
            }
        }
    }
}

5.附上本人封裝的CommonWebView以及使用方式

public class CommonWebView extends WebView{
    private Context context;
    private WebSettings settings;
    private VideoWebFactory videoWebFactory;
    private WebFileFactory webFileFactory;
    private ValueCallback<Uri> mUM;
    private ValueCallback<Uri[]> mUMA;
    private OnFileSelected onFileSelected;
    public CommonWebView(Context context) {
        super(context);
        this.context =context;
        init();
    }
    public CommonWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context =context;
        init();
    }
    public CommonWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.context =context;
        init();
    }
 
    private void init(){
        //基礎(chǔ)設(shè)置
        settings =getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setUseWideViewPort(true); // 關(guān)鍵點(diǎn)
        settings.setLoadWithOverviewMode(true);
        if (Build.VERSION.SDK_INT >= 21) {
            settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
            setLayerType(View.LAYER_TYPE_HARDWARE, null);
        } else if (Build.VERSION.SDK_INT >= 19) {
            setLayerType(View.LAYER_TYPE_HARDWARE, null);
        } else if (Build.VERSION.SDK_INT < 19) {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
        //設(shè)置webview安全性
        setWebViewSecurity();
        setWebViewClient();
    }
    
    private void setWebViewClient(){
        setWebViewClient(new CommonWebViewClient());
    }
    //支持視頻播放
    public void setSupportVideo(CommonWebChromeClient webChromeClient){
        videoWebFactory = new VideoWebFactory(context,this);
        setWebChromeClient(webChromeClient);
    }
    //文件上傳
    public CommonWebView setSupportFile(CommonWebChromeClient webChromeClient){
        webFileFactory = new WebFileFactory(context);
        settings.setAllowFileAccess(true);
        setSupportVideo(webChromeClient);
        return this;
    }
   public void setOnFileSelected(OnFileSelected onFileSelected) {
       this.onFileSelected = onFileSelected;
   }
   public WebFileFactory getWebFileFactory() {
       return webFileFactory;
   }
   public class CommonWebViewClient extends WebViewClient{
       @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
             loadUrl(url);
            return true;
        }
   }
   
   public class CommonWebChromeClient extends WebChromeClient{
       /*** 視頻播放相關(guān)的方法 **/
        @Override
        public View getVideoLoadingProgressView() {
            if(videoWebFactory!=null){
                return videoWebFactory.getVideoLoadingProgressView();
            }
            return null;
        }
        @Override
        public void onShowCustomView(View view, CustomViewCallback callback) {
            if(videoWebFactory!=null){
                videoWebFactory.showCustomView(view, callback);
            }
        }
        @Override
        public void onHideCustomView() {
            if(videoWebFactory!=null){
                videoWebFactory.hideCustomView();
            }
        }
        /**
         * 文件上傳
         * */
        //For Android 3.0+
        public void openFileChooser(ValueCallback<Uri> uploadMsg){
            mUM = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("*/*");
            ((Activity)context).startActivityForResult(Intent.createChooser(i,"File Chooser"), WebFileFactory.SELECT_PHOTO);
        }
        // For Android 3.0+, above method not supported in some android 3+ versions, in such case we use this
        public void openFileChooser(ValueCallback uploadMsg, String acceptType){
            mUM = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("*/*");
            ((Activity)context).startActivityForResult(Intent.createChooser(i, "File Browser"),WebFileFactory.SELECT_PHOTO);
        }
        //For Android 4.1+ 只能選擇一個(gè)文件
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
            mUM = uploadMsg;
            if(onFileSelected!=null){
                onFileSelected.onSelectOne(mUM,mUMA);
            }
            if(webFileFactory!=null){
                webFileFactory.setmUM(mUM);
                webFileFactory.showPhotoSelectForOne();
            }
        }
       //For Android 5.0+ 多個(gè)文件選擇
        public boolean onShowFileChooser(
                WebView webView, ValueCallback<Uri[]> filePathCallback,
                WebChromeClient.FileChooserParams fileChooserParams){
            mUMA = filePathCallback;
            if(onFileSelected!=null){
                onFileSelected.onSelect(mUM,mUMA);
            }
            if(webFileFactory!=null){
                webFileFactory.setmUMA(mUMA);
                webFileFactory.showPhotoSelect();
            }
            return true;
        }
   } 
    /**
     * 設(shè)置webview安全性
     */
    private void setWebViewSecurity(){
        try {
            removeJavascriptInterface("searchBoxJavaBridge_");
            removeJavascriptInterface("accessibility");
            removeJavascriptInterface("accessibilityTraversal");   
            getSettings().setSavePassword(false);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
            }
        } catch (Exception e) {
        }
    }
    
    public interface OnFileSelected{
        void onSelectOne(ValueCallback<Uri> mUM,   ValueCallback<Uri[]> mUMA);
        void onSelect(ValueCallback<Uri> mUM,   ValueCallback<Uri[]> mUMA);
    }
}
支持視頻播放
webView.setSupportVideo(webView.new CommonWebChromeClient());
支持文件上傳
webView.setSupportFile(wbw_web.new CommonWebChromeClient());
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市偷办,隨后出現(xiàn)的幾起案子艰额,更是在濱河造成了極大的恐慌,老刑警劉巖椒涯,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柄沮,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)祖搓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門狱意,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人拯欧,你說(shuō)我怎么就攤上這事详囤。” “怎么了镐作?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵藏姐,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我该贾,道長(zhǎng)羔杨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任杨蛋,我火速辦了婚禮问畅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘六荒。我一直安慰自己护姆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布掏击。 她就那樣靜靜地躺著卵皂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪砚亭。 梳的紋絲不亂的頭發(fā)上灯变,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音捅膘,去河邊找鬼添祸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛寻仗,可吹牛的內(nèi)容都是我干的刃泌。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼署尤,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耙替!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起曹体,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤俗扇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后箕别,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铜幽,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滞谢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了除抛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片爹凹。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖镶殷,靈堂內(nèi)的尸體忽然破棺而出禾酱,到底是詐尸還是另有隱情,我是刑警寧澤绘趋,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布颤陶,位于F島的核電站,受9級(jí)特大地震影響陷遮,放射性物質(zhì)發(fā)生泄漏滓走。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一帽馋、第九天 我趴在偏房一處隱蔽的房頂上張望搅方。 院中可真熱鬧,春花似錦绽族、人聲如沸姨涡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)涛漂。三九已至,卻和暖如春检诗,著一層夾襖步出監(jiān)牢的瞬間匈仗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工逢慌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悠轩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓攻泼,卻偏偏與公主長(zhǎng)得像火架,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子坠韩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容