Glide源碼分析二——Request相關(guān)

RequestManagerRetriever

Glide在構(gòu)造時(shí)創(chuàng)建了RequestManagerRetriever,用于根據(jù)參數(shù)(Application、Activity、FragmentActivity濒生、Fragment、View)獲取RequestManager。

如果沒有創(chuàng)建RequestManager润绎,則會(huì)通過RequestManagerFactory創(chuàng)建。

// RequestManagerRetriever.java

private volatile RequestManager applicationManager;

public RequestManagerRetriever(@Nullable RequestManagerFactory factory) {
    // 如果沒有
    this.factory = factory != null ? factory : DEFAULT_FACTORY;
    handler = new Handler(Looper.getMainLooper(), this /* Callback */);
}


// RequestManager工廠類
public interface RequestManagerFactory {
    @NonNull
    RequestManager build(
        @NonNull Glide glide,
        @NonNull Lifecycle lifecycle,
        @NonNull RequestManagerTreeNode requestManagerTreeNode,
        @NonNull Context context);
}

private static final RequestManagerFactory DEFAULT_FACTORY =
      new RequestManagerFactory() {
        @NonNull
        @Override
        public RequestManager build(
            @NonNull Glide glide,
            @NonNull Lifecycle lifecycle,
            @NonNull RequestManagerTreeNode requestManagerTreeNode,
            @NonNull Context context) {
          return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
        }
      };
      
      
public RequestManager get(@NonNull Context context) {
    if (context == null) {
      // ... 省略拋異常代碼
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
    
      // 如果是在主線程匙监,且context不是Application凡橱,則獲取對(duì)應(yīng)頁面(Activity、Fragment)的RequestManager(該RequestManger對(duì)應(yīng)著一個(gè)RequestManagerFragment)
      
      if (context instanceof FragmentActivity) {
        return get((FragmentActivity) context);
      } else if (context instanceof Activity) {
        return get((Activity) context);
      } else if (context instanceof ContextWrapper
          && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
        return get(((ContextWrapper) context).getBaseContext());
      }
    }

    // 如果是在子線程或context是Application亭姥,則返回ApplicationManager(跟隨應(yīng)用生命周期)
    return getApplicationManager(context);
}

private RequestManager getApplicationManager(@NonNull Context context) {
    
    if (applicationManager == null) {
      synchronized (this) {
        if (applicationManager == null) {
          Glide glide = Glide.get(context.getApplicationContext());
          
          // 利用工廠類創(chuàng)建一個(gè)跟隨應(yīng)用聲明周期的RequestManger
          applicationManager =
              factory.build(
                  glide,
                  new ApplicationLifecycle(),
                  new EmptyRequestManagerTreeNode(),
                  context.getApplicationContext());
        }
      }
    }

    return applicationManager;
}

public RequestManager get(FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      
      // 獲取SupportFragmentManger稼钩,用于查找或添加SupportRequestMangerFragment,之后利用SupportRequestMangerFragment獲取RequestManger
      FragmentManager fm = activity.getSupportFragmentManager();
      return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
}

private RequestManager supportFragmentGet(
      @NonNull Context context,
      @NonNull FragmentManager fm,
      @Nullable Fragment parentHint,
      boolean isParentVisible) {

    // 獲取SupportRequestManagerFragment
    SupportRequestManagerFragment current =
        getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
        
    // 從SupportRequestManagerFragment中獲取RequestManger
    RequestManager requestManager = current.getRequestManager();
    
    // 如果SupportRequestManagerFragment沒有RequetManger达罗,則創(chuàng)建RequestManager并設(shè)置給SupportRequestManagerFragment
    if (requestManager == null) {
      
      Glide glide = Glide.get(context);
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
}


// 正在通過FragmentManger添加的RequestManagerFragment坝撑,之后會(huì)通過handler從該集合中移除
final Map<android.app.FragmentManager, RequestManagerFragment> pendingRequestManagerFragments =
      new HashMap<>();
      
final Map<FragmentManager, SupportRequestManagerFragment> pendingSupportRequestManagerFragments =
      new HashMap<>();

@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
      @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
    
    // 是否有已經(jīng)添加了的RequeetFragment
    SupportRequestManagerFragment current =
        (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      
      // 是否有正在添加的RSupportequestFragment静秆,沒有的話,創(chuàng)建一個(gè)巡李,并通過FragmentManager添加抚笔,同時(shí)放入pendingSupportRequestManagerFragments中,待添加完成后會(huì)通過Handler從集合中移除
      current = pendingSupportRequestManagerFragments.get(fm);
      if (current == null) {
        current = new SupportRequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        pendingSupportRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        
        // handler發(fā)送消息侨拦,從列表中移除正在添加的fragment
        handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
}


其他get(Activity)殊橙、get(Fragment)、get(View)都差不多

public RequestManager get(@NonNull View view) {
    if (Util.isOnBackgroundThread()) {
      return get(view.getContext().getApplicationContext());
    }

    ...
    // 找到context對(duì)應(yīng)的Activity
    Activity activity = findActivity(view.getContext());
    
    if (activity == null) {
      return get(view.getContext().getApplicationContext());
    }

    
    if (activity instanceof FragmentActivity) {
      // 遞歸遍歷view的parent狱从,如果view的哪個(gè)parent是已經(jīng)Added的SupportFragment的rootView膨蛮,則返回該Fragment
      Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
      
      // 獲取Fragment或Activity的SupportRequestManagerFragment的RequestManaager
      return fragment != null ? get(fragment) : get((FragmentActivity) activity);
    }

    // 和findSupportFragment(...)類似,只是這里返回的是android.app.Fragment
    android.app.Fragment fragment = findFragment(view, activity);
    if (fragment == null) {
      return get(activity);
    }
    return get(fragment);
}


// 臨時(shí)map季研,存儲(chǔ)Fragment和它的rootView
private final ArrayMap<View, Fragment> tempViewToSupportFragment = new ArrayMap<>();

// 遞歸遍歷view的parent敞葛,如果view或view的哪個(gè)parent是已經(jīng)Added的Fragment的rootView,則返回該Fragment   
private Fragment findSupportFragment(@NonNull View target, @NonNull FragmentActivity activity) {
    tempViewToSupportFragment.clear();
    
    // 獲取Activity已添加的所有Fragment及每個(gè)Fragment的子Fragment与涡,及對(duì)應(yīng)的fragment的RootView
    findAllSupportFragmentsWithViews(
        activity.getSupportFragmentManager().getFragments(), tempViewToSupportFragment);
        
    // 如果view或者view的parent是某個(gè)已Added的fragment的rootView惹谐,則返回該Fragment    
    Fragment result = null;
    View activityRoot = activity.findViewById(android.R.id.content);
    View current = target;
    while (!current.equals(activityRoot)) {
      result = tempViewToSupportFragment.get(current);
      if (result != null) {
        break;
      }
      if (current.getParent() instanceof View) {
        current = (View) current.getParent();
      } else {
        break;
      }
    }

    tempViewToSupportFragment.clear();
    return result;
}

// 遍歷topLevelFragments及每個(gè)Fragment的子Fragment,將Fragment和對(duì)應(yīng)的rootView放入臨時(shí)map中
private static void findAllSupportFragmentsWithViews(
      @Nullable Collection<Fragment> topLevelFragments, @NonNull Map<View, Fragment> result) {
    if (topLevelFragments == null) {
      return;
    }
    for (Fragment fragment : topLevelFragments) {
      FragmentManager may contain null values, see #1991.
      if (fragment == null || fragment.getView() == null) {
        continue;
      }
      result.put(fragment.getView(), fragment);
      findAllSupportFragmentsWithViews(fragment.getChildFragmentManager().getFragments(), result);
    }
}

get(view)的主要工作是:
遍歷該View及其parent驼卖,如果該view或其parent是該view所在的Activity的某個(gè)已經(jīng)added的Fragment的rootView氨肌,則返回該Fragment的SupportRequestManagerFragment/RequestManagerFragment的RequestManager;如果該view所在的Activity沒有添加Fragment或該view及其parent不是某個(gè)Fragment的rootView款慨,則獲取該view所在的Activity的SupportRequestManagerFragment/RequestManagerFragment的RequestManager儒飒。

public RequestManager get(@NonNull Fragment fragment) {
    
    if (Util.isOnBackgroundThread()) {
      return get(fragment.getContext().getApplicationContext());
    } else {
      FragmentManager fm = fragment.getChildFragmentManager();
      
      // 找到Fragment已添加的SupportRequestManagerFragment,并返回其RequestManager
      return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
    }
}

get(androidx.fragment.app.Fragment)和get(android.app.Fragment)差不多檩奠,都是找到Fragment已添加的SupportRequestManagerFragment/RequestManagerFragment桩了,并返回其RequestManager。

RequestManagerFragment

內(nèi)含lifecycle埠戳,當(dāng)RequestManagerFragment聲明周期發(fā)生變化時(shí)井誉,會(huì)通過lifecycle通知LifecycleListener,而RequestManager實(shí)現(xiàn)了LifecycleListener整胃,并在創(chuàng)建時(shí)被添加到了lifecycle颗圣。

RequestManger

用于生成RequestBuilder、控制Request屁使,內(nèi)部使用RequestTracker控制Request的開始在岂、暫停、銷毀等蛮寂。

RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
      
    this.glide = glide;
    this.lifecycle = lifecycle;
    this.requestTracker = requestTracker;
    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    ...
    
}

public synchronized void pauseRequests() {
    requestTracker.pauseRequests();
}

public synchronized void resumeRequests() {
    requestTracker.resumeRequests();
}

synchronized void track(Target<?> target, Request request) {
    targetTracker.track(target);

    // 內(nèi)部調(diào)用Request#begin()開始請(qǐng)求數(shù)據(jù)
    requestTracker.runRequest(request);
}

...

@Override
public synchronized void onStart() {
    resumeRequests();
    targetTracker.onStart();
}

...

public <ResourceType> RequestBuilder<ResourceType> as(Class<ResourceType> resourceClass) {
    return new RequestBuilder<>(glide, this, resourceClass, context);
}

public RequestBuilder<Drawable> asDrawable() {
    return as(Drawable.class);
}

public RequestBuilder<Drawable> load(@Nullable String string) {
    return asDrawable().load(string);
}

...

RequestBuilder

用于生成Request蔽午。

// load方法會(huì)保存請(qǐng)求參數(shù)model
public RequestBuilder<TranscodeType> load(@Nullable Object model) {
    return loadGeneric(model);
}


private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
    this.model = model;
    isModelSet = true;
    return this;
}

// 構(gòu)造request,并啟動(dòng)
private <Y extends Target<TranscodeType>> Y into(
      Y target,
      RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
    ...

    Request request = buildRequest(target, targetListener, options, callbackExecutor);

    Request previous = target.getRequest();
    
    // 如果request和target之前的request一樣酬蹋,且之前的request未完成或能使用內(nèi)存中已完成的request及老,則復(fù)用reqeust
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
      
      // 如果請(qǐng)求完成抽莱,調(diào)用begin()重新開始確保重新傳遞結(jié)果,觸發(fā) RequestListeners 和 Targets骄恶。如果請(qǐng)求失敗食铐,調(diào)用begin()重新開始將重新啟動(dòng)請(qǐng)求,給它一次完成的機(jī)會(huì)僧鲁。如果請(qǐng)求已經(jīng)在運(yùn)行虐呻,我們可以讓它繼續(xù)運(yùn)行而不會(huì)中斷。
      if (!Preconditions.checkNotNull(previous).isRunning()) {
        
        previous.begin();
      }
      return target;
    }

    // 清除requestManager中保存的target和對(duì)應(yīng)的Request(如果有的話悔捶,會(huì)分別從targetTracker和requestTracker中移除target和request铃慷,并將target.setRequest(null))
    requestManager.clear(target);
    target.setRequest(request);
    // 將target和對(duì)應(yīng)的request保存在requestManager中单芜,并啟動(dòng)請(qǐng)求(request.begin())
    requestManager.track(target, request);

    return target;
}

// buildRequest(...)直接走的這個(gè)方法
private Request buildRequestRecursive(
      Object requestLock,
      Target<TranscodeType> target,
      @Nullable RequestListener<TranscodeType> targetListener,
      @Nullable RequestCoordinator parentCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      BaseRequestOptions<?> requestOptions,
      Executor callbackExecutor) {

    ... // 省略一些代碼

    Request mainRequest =
        buildThumbnailRequestRecursive(
            requestLock,
            target,
            targetListener,
            parentCoordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight,
            requestOptions,
            callbackExecutor);

    if (errorRequestCoordinator == null) {
      return mainRequest;
    }

    ... // 省略一些代碼
}

private Request buildThumbnailRequestRecursive(
      Object requestLock,
      Target<TranscodeType> target,
      RequestListener<TranscodeType> targetListener,
      RequestCoordinator parentCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      BaseRequestOptions<?> requestOptions,
      Executor callbackExecutor) {
    if (thumbnailBuilder != null) {
      ...
      return coordinator;
    } else if (thumbSizeMultiplier != null) {
      ...
      return coordinator;
    } else {
      // Base case: no thumbnail.
      return obtainRequest(
          requestLock,
          target,
          targetListener,
          requestOptions,
          parentCoordinator,
          transitionOptions,
          priority,
          overrideWidth,
          overrideHeight,
          callbackExecutor);
    }
}

private Request obtainRequest(
      Object requestLock,
      Target<TranscodeType> target,
      RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> requestOptions,
      RequestCoordinator requestCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      Executor callbackExecutor) {
      
    // 返回一個(gè)SingleRequest
    return SingleRequest.obtain(
        context,
        glideContext,
        requestLock,
        model,
        transcodeClass,
        requestOptions,
        overrideWidth,
        overrideHeight,
        priority,
        target,
        targetListener,
        requestListeners,
        requestCoordinator,
        glideContext.getEngine(), // 獲取engine
        transitionOptions.getTransitionFactory(),
        callbackExecutor);
}

SingleRequest

public final class SingleRequest<R> implements Request, SizeReadyCallback, ResourceCallback {
    
    
    public static <R> SingleRequest<R> obtain(
      ...
      Object model,
      Class<R> transcodeClass,
      BaseRequestOptions<?> requestOptions,
      int overrideWidth,
      int overrideHeight,
      Target<R> target,
      RequestListener<R> targetListener,
      Engine engine,
      Executor callbackExecutor) {
        return new SingleRequest<>(
            ...
            model,
            transcodeClass,
            requestOptions,
            overrideWidth,
            overrideHeight,
            target,
            targetListener,
            engine,
            callbackExecutor);
    }

    private SingleRequest(
      ...
      @Nullable Object model,
      Class<R> transcodeClass,
      BaseRequestOptions<?> requestOptions,
      int overrideWidth,
      int overrideHeight,
      Target<R> target,
      RequestListener<R> targetListener,
      Engine engine,
      Executor callbackExecutor) {
        this.model = model;
        this.transcodeClass = transcodeClass;
        this.requestOptions = requestOptions;
        this.overrideWidth = overrideWidth;
        this.overrideHeight = overrideHeight;
        this.target = target;
        this.targetListener = targetListener;
        this.engine = engine;
        this.callbackExecutor = callbackExecutor;
        status = Status.PENDING;
        ...
    }
    
    
  // 開始執(zhí)行請(qǐng)求
  @Override
  public void begin() {
    synchronized (requestLock) {
      ...
      if (model == null) {
        ...
        onLoadFailed(new GlideException("Received null model"), logLevel);
        return;
      }

      if (status == Status.RUNNING) {
        throw new IllegalArgumentException("Cannot restart a running request");
      }

      // 如果我們?cè)谡?qǐng)求完成后重新啟動(dòng)請(qǐng)求時(shí)(通常通過諸如 notifyDataSetChanged 之類的方式蜕该,它啟動(dòng)對(duì)相同目標(biāo)或視圖的相同請(qǐng)求),我們可以簡(jiǎn)單地使用我們上次檢索到的資源和大小并跳過獲取新大小, 開始新的加載等洲鸠。如果用戶需要在視圖大小更改后重新啟動(dòng)請(qǐng)求堂淡,則需要在開始新加載之前顯式清除視圖或目標(biāo)。
      if (status == Status.COMPLETE) {
        onResourceReady(resource, DataSource.MEMORY_CACHE);
        return;
      }

      // 如果請(qǐng)求不是運(yùn)行中或完成狀態(tài)扒腕,重新啟動(dòng)它可以被看作是一個(gè)新的請(qǐng)求绢淀,且可以從頭開始執(zhí)行。
      status = Status.WAITING_FOR_SIZE;
      if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        // 如果設(shè)置了overrideWidth和overrideHeight瘾腰,則修改status為running皆的,并通過engine開始加載圖片
        onSizeReady(overrideWidth, overrideHeight);
      } else {
        // 沒有size,則先通過Target獲取大小
        target.getSize(this);
      }

      if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
          && canNotifyStatusChanged()) {
          
          // 獲取placeHolderDrawable蹋盆,并回調(diào)target#onLoadStarted(drawable)费薄,如果是ImageViewTarget則會(huì)讓ImageView加載drawable
        target.onLoadStarted(getPlaceholderDrawable());
      }
      
    }
  }
  
  
  public void onSizeReady(int width, int height) {
    stateVerifier.throwIfRecycled();
    synchronized (requestLock) {
      
      if (status != Status.WAITING_FOR_SIZE) {
        return;
      }
      status = Status.RUNNING;

      ... // 省略部分對(duì)width和height的操作,主要是乘以sizeMultiplier
      
      // 加載圖片
      loadStatus =
          engine.load(
              glideContext,
              model,
              requestOptions.getSignature(),
              this.width,
              this.height,
              requestOptions.getResourceClass(),
              transcodeClass,
              priority,
              requestOptions.getDiskCacheStrategy(),
              requestOptions.getTransformations(),
              requestOptions.isTransformationRequired(),
              requestOptions.isScaleOnlyOrNoTransform(),
              requestOptions.getOptions(),
              requestOptions.isMemoryCacheable(),
              requestOptions.getUseUnlimitedSourceGeneratorsPool(),
              requestOptions.getUseAnimationPool(),
              requestOptions.getOnlyRetrieveFromCache(),
              this,
              callbackExecutor);

      ...
    }
  }
  
  
  public void onResourceReady(Resource<?> resource, DataSource dataSource) {
    ...
    Resource<?> toRelease = null;
    try {
      synchronized (requestLock) {
        loadStatus = null;
        if (resource == null) {
          GlideException exception = new GlideException("...");
          onLoadFailed(exception);
          return;
        }

        // transcodeClass就是我們想要的類型栖雾,例如Drawable楞抡、Bitmap...
        Object received = resource.get();
        if (received == null || !transcodeClass.isAssignableFrom(received.getClass())) {
          toRelease = resource;
          this.resource = null;
          GlideException exception = new GlideException("..."));
          onLoadFailed(exception);
          return;
        }

        ...
        
        // 資源準(zhǔn)備好后通知target加載資源
        onResourceReady((Resource<R>) resource, (R) received, dataSource);
      }
    } finally {
      // 資源沒有被使用需要釋放掉
      if (toRelease != null) {
        engine.release(toRelease);
      }
    }
  }
  
  private void onResourceReady(Resource<R> resource, R result, DataSource dataSource) {
    
    boolean isFirstResource = isFirstReadyResource();
    
    // 修改狀態(tài)為complete
    status = Status.COMPLETE;
    this.resource = resource;

    isCallingCallbacks = true;
    try {
    
      // 是否有任何RequestListener已經(jīng)通過onResourceReady(...)通知target加載了資源
      boolean anyListenerHandledUpdatingTarget = false;
      if (requestListeners != null) {
        for (RequestListener<R> listener : requestListeners) {
          anyListenerHandledUpdatingTarget |=
              listener.onResourceReady(result, model, target, dataSource, isFirstResource);
        }
      }
      anyListenerHandledUpdatingTarget |=
          targetListener != null
              && targetListener.onResourceReady(result, model, target, dataSource, isFirstResource);

      // 如果還沒有通過RequestListener#onResourceReady(...)更新target,則直接調(diào)用Target#onResourceReady(...)通知target加載資源
      if (!anyListenerHandledUpdatingTarget) {
        Transition<? super R> animation = animationFactory.build(dataSource, isFirstResource);
        target.onResourceReady(result, animation);
      }
    } finally {
      isCallingCallbacks = false;
    }

    // 通知父RequestCoordinator請(qǐng)求成功了
    notifyLoadSuccess();
  }
    
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末析藕,一起剝皮案震驚了整個(gè)濱河市召廷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌账胧,老刑警劉巖竞慢,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異治泥,居然都是意外死亡筹煮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門车摄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寺谤,“玉大人仑鸥,你說我怎么就攤上這事”淦ǎ” “怎么了眼俊?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)粟关。 經(jīng)常有香客問我疮胖,道長(zhǎng),這世上最難降的妖魔是什么闷板? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任澎灸,我火速辦了婚禮,結(jié)果婚禮上遮晚,老公的妹妹穿的比我還像新娘性昭。我一直安慰自己,他們只是感情好县遣,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布糜颠。 她就那樣靜靜地躺著,像睡著了一般萧求。 火紅的嫁衣襯著肌膚如雪其兴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天夸政,我揣著相機(jī)與錄音元旬,去河邊找鬼。 笑死守问,一個(gè)胖子當(dāng)著我的面吹牛匀归,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播酪碘,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼朋譬,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了兴垦?” 一聲冷哼從身側(cè)響起徙赢,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎探越,沒想到半個(gè)月后狡赐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钦幔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年枕屉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鲤氢。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡搀擂,死狀恐怖西潘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哨颂,我是刑警寧澤喷市,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站威恼,受9級(jí)特大地震影響品姓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜箫措,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一腹备、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧斤蔓,春花似錦植酥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至喇伯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拨与,已是汗流浹背稻据。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留买喧,地道東北人捻悯。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像淤毛,于是被迫代替她去往敵國(guó)和親今缚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

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