Launcher3 快捷图标点击事件绑定到启动acitivity-API28

  1. void onClick(View v, String sourceContainer)->
    // ItemClickHandler.java
    // 10.0不再是ItemClickHandler.INSTANCE,只是换了一个写法返回依旧是一个OnClickListener

  2. onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher, sourceContainer);

  3. startAppShortcutOrInfoActivity(v, shortcut, launcher, sourceContainer);
    launcher.startActivitySafely(v, intent, item);
    要注意intent来自ItemInfo,如果支持FLAG_SUPPORTS_WEB_UI,会置空package

    private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher,
           @Nullable String sourceContainer) {
       if (TestProtocol.sDebugTracing) {
           android.util.Log.d(TestProtocol.NO_START_TAG,
                   "startAppShortcutOrInfoActivity");
       }
       Intent intent;
       if (item instanceof PromiseAppInfo) {
           PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item;
           intent = promiseAppInfo.getMarketIntent(launcher);
       } else {
           intent = item.getIntent();
       }
       if (intent == null) {
           throw new IllegalArgumentException("Input must have a valid intent");
       }
       if (item instanceof WorkspaceItemInfo) {
           WorkspaceItemInfo si = (WorkspaceItemInfo) item;
           if (si.hasStatusFlag(WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI)
                   && Intent.ACTION_VIEW.equals(intent.getAction())) {
               // make a copy of the intent that has the package set to null
               // we do this because the platform sometimes disables instant
               // apps temporarily (triggered by the user) and fallbacks to the
               // web ui. This only works though if the package isn't set
               intent = new Intent(intent);
               intent.setPackage(null);
           }
       }
       if (v != null && launcher.getAppTransitionManager().supportsAdaptiveIconAnimation()) {
           // Preload the icon to reduce latency b/w swapping the floating view with the original.
           FloatingIconView.fetchIcon(launcher, v, item, true /* isOpening */);
       }
       launcher.startActivitySafely(v, intent, item, sourceContainer);
    }
    
  4. startActivitySafely(View v, Intent intent, ItemInfo item,@Nullable String sourceContainer)返回值boolean
    // Launcher.java
    中间有一个遇到意外等待重启的流程,这里我们走正常流程
    super.startActivitySafely(v, intent, item, sourceContainer)

  5. startActivitySafely(View v, Intent intent, @Nullable ItemInfo item,
    @Nullable String sourceContainer)返回值boolean
    //BaseDraggingActivity.java
    这里获取Bundle optsBundle = (v != null) ? getActivityLaunchOptionsAsBundle(v) : null;
    view不为空的情况下intent.setSourceBounds(getViewBounds(v))
    因为我们是Shortcuts所以走下面的方法

  6. startShortcutIntentSafely(intent, optsBundle, item, sourceContainer)
    不是深度链接调用startActivity(intent, optsBundle);

  7. startActivity(Intent intent, @Nullable Bundle options)
    //Activity.java
    因为options != null所以调用下面方法

  8. startActivityForResult(intent, -1, options);
    //Activity.java
    因为mParent==null所以调用下面方法

    Instrumentation.ActivityResult ar =
        mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, this,
            intent, requestCode, options);
    

    参数说明:requestCode=-1
    mInstrumentation和mToken来自Activity.attach()的参数传入,
    调用者是performLaunchActivity()将ActivityThread的mInstrumentation和参数ActivityClientRecor的.token传给activity
    ActivityThread在main()方法创建自己时调用了自己的attach(false, startSeq)
    因为false所以没有走new Instrumentation();
    所以只有ActivityThread的handleBindApplication(AppBindData data)
    因为不是ClassLoader.loadClass(类名)就是new Instrumentation()所以mInstrumentation肯定不为空
    //TODO后面再分享如果自己修改默认是Instrumentation
    mToken = ActivityClientRecord.token

  9. execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,
    Intent intent, int requestCode, Bundle options) 返回值ActivityResult
    //Instrumentation.java
    参数说明:who是当前activity,contextThread是从当前activity的ActivityThread获取
    最终调用了

    IApplicationThread whoThread = (IApplicationThread) contextThread;
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    //因为onProvideReferrer()返回空所以不要给Intent添加Intent.EXTRA_REFERRER
    int result = ActivityTaskManager.getService()
                    .startActivity(whoThread, who.getBasePackageName(), intent,
                            intent.resolveTypeIfNeeded(who.getContentResolver()),
                            token, target != null ? target.mEmbeddedID : null,
                            requestCode, 0, null, options)
    
  10. static getService()
    //ActivityTaskManager.java
    IActivityTaskManagerSingleton.get()
    是一个Singleton类静态实现,最终调用其中的oncreate方法
    返回的是IActivityTaskManager的binder从ServiceManager的缓存中,找不到就去ServiceManagerNative最终去native层

    • SytemServer的main方法 new SystemServer.run()
    • run()->startBootstrapServices()->
    • 最终调用了ActivityTaskManagerService atm = mSystemServiceManager.startService(
      ActivityTaskManagerService.Lifecycle.class).getService()
    • 通过反射构造了ActivityTaskManagerService.Lifecycle的实例,然后调用它的startService()方法
    • startService()中执行了两个方法,重点是publishBinderService:
      publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
      mService.start();
    • publishBinderService这个是其父类SystemService的方法
    • publishBinderService有多个重载方法,部分缺少参数默认值如下:allowIsolated=false, dumpPriority=SystemService。DUMP_FLAG_PRIORITY_DEFAULT
    • 最终调用了ServiceManager.addService(name, service, allowIsolated, dumpPriority)完成注册
    private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
         new Singleton<IActivityTaskManager>() {
             @Override
             protected IActivityTaskManager create() {
                  final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                  return IActivityTaskManager.Stub.asInterface(b);
          }
    };
    
    //ServiceManager.java
    public static IBinder getService(String name) {
        try {
           IBinder service = sCache.get(name);
           if (service != null) {
               return service;
            } else {
                 return Binder.allowBlocking(rawGetService(name));
           }
         } catch (RemoteException e) {
             Log.e(TAG, "error in getService", e);
         }
        return null;
    }
    
  11. startActivity()->startActivityAsUser()
    //ActivityTaskManagerService.java
    Linux uid/100000 4.1以上版本从100000开始,root是从0开始,每个用户加100000

    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }

    int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
            boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivityAsUser");

        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute();

    }
  1. execute()
    // ActivityStarter.java
    因为setMayWait(userId),所以mRequest.mayWait = true;
    所以调用startActivityMayWait()内部调用了startActivity()

    startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
                        mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup,
                        mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart)
    
  2. startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
    voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
    allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
    allowBackgroundActivityStart)

  3. startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
    mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
    mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
    mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
    mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
    mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
    mRequest.outActivity, mRequest.inTask, mRequest.reason,
    mRequest.allowPendingRemoteAnimationRegistryLookup);
    //ActivityStarter.java

  4. mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
    aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
    callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
    options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
    inTask, allowPendingRemoteAnimationRegistryLookup);
    //ActivityStarter.java
    // 方法内部创建了ActivityRecord

  5. startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
    true /* doResume */, checkedOptions, inTask, outActivity)
    //ActivityStarter.java

  6. result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
    startFlags, doResume, options, inTask, outActivity);

  7. mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack,
    mStartActivity, mOptions)
    // mSupervisor是在AMS中创建最终传入ActivityStarter
    // ActivityStackSupervisor.java
    // mTargetStack 通过新建TaskRecord创建
    // TO do有空细化

  8. targetStack.resumeTopActivityInnerLocked(target,
    targetOptions)
    // ActivityStack.java

  9. mStackSupervisor.startSpecificActivityLocked(target,
    targetOptions)
    // ActivityStackSupervisor.java

  10. Service.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
    "activity", r.intent.getComponent(), false, false, true)
    // ActivityManagerService.java
    // 经过一阵startProcessLocked重载方法传递

  11. startProcess(hostingType, entryPoint, app,
    uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
    invokeWith, startTime)

  12. Process.start(entryPoint,
    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
    app.info.dataDir, invokeWith,
    new String[] {PROC_START_SEQ_IDENT + app.startSeq})

  13. zygoteProcess.start(processClass, niceName, uid, gid, gids,
    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
    abi, instructionSet, appDataDir, invokeWith, zygoteArgs)

  14. startViaZygote(processClass, niceName, uid, gid, gids,
    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
    abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote /,
    zygoteArgs)

  15. startViaZygote(processClass, niceName, uid, gid, gids,
    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
    abi, instructionSet, appDataDir, invokeWith, false /
    startChildZygote /,
    zygoteArgs)

  16. zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote)
    openZygoteSocketIfNeeded(abi)方法使用socket与ZygoteProcess进程通信,
    zygoteSendArgsAndGetResult方法主要写入参数
    其中processClass ="android.app.ActivityThread",通过Zygote进程来Fork出一个新的进程,并执行 "android.app.ActivityThread"的main方法

  17. **[ZygoteInit.java] main()****

    说明:Zygote先fork出SystemServer进程,接着进入循环等待,用来接收Socket发来的消息,用来fork出其他应用进程,比如Launcher

  18. [ZygoteConnection.java] processOneCommand()

    说明:通过forkAndSpecialize()来fork出Launcher的子进程,并执行handleChildProc,进入子进程的处理

  19. [ZygoteConnection.java] handleChildProc()
    说明:进行子进程的操作,最终获得需要执行的ActivityThread的main()

  20. [ZygoteConnection.java] zygoteInit()进行一些环境的初始化、启动Binder进程等操作:

  21. 把之前传来的"android.app.ActivityThread" 传递给findStaticMain():

    通过反射,拿到ActivityThread的main()方法:
    把反射得来的ActivityThread main()入口返回给ZygoteInit的main,通过caller.run()进行调用:

  22. main(String[] args)

    //ActivityThread.java

ActivityThread thread = new ActivityThread();
//ActivityThread实例化时其属性mAppThread也实例化
//final ApplicationThread mAppThread = new ApplicationThread();
thread.attach(false, startSeq);
  1. attach(boolean system, long startSeq)
    //ActivityThread.java

    • ActivityManager.getService()
      //ActivityManager.java

      1. ServiceManager.getService(Context.ACTIVITY_SERVICE)

        BinderInternal.getContextObject()最终调用native层方法获取的是ActivityManagerService的binder

        简单叙述AMS注册过程

        SystemServer的static void main(String[] args)

        ---->run()

        ----> mSystemServiceManager = new SystemServiceManager(mSystemContext);

        ---->startBootstrapServices()
        -------->1. mActivityManagerService = mSystemServiceManager.startService(
        ActivityManagerService.Lifecycle.class).getService();
        -------->SystemServiceManager的startService(Class<T> serviceClass)
        -------->最终反射实例调用,因为ActivityManagerService.Lifecycle extends SystemService service.onStart()
        -------->ActivityManagerService.Lifecycle.onStart()
        -------->因为构造Lifecycle时内部mService = new ActivityManagerService(context, sAtm);
        在构造方法内部创建了mStackSupervisor = createStackSupervisor();
        protected ActivityStackSupervisor
        -------->ActivityManagerService.Lifecycle.getService()返回内部mService
        -------->2.mActivityManagerService.setSystemProcess();在startBootstrapServices()里面调用
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
        DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO)

      2. mgr.attachApplication(mAppThread, startSeq)
        // ActivityManagerService.java

  2. attachApplicationLocked(thread, callingPid, callingUid, startSeq)
    // ActivityManagerService.java
    //----->thread.bindApplication()
    这里的thread是最上面提到的ApplicationThread是ActivityThread的内部类,是binder

  3. sendMessage(H.BIND_APPLICATION, data);
    //ActivityThread.java

  4. 最终走到H类的handleBindApplication(data)

    • InstrumentationInfo ii = new ApplicationPackageManager(null, getPackageManager())
      .getInstrumentationInfo(data.instrumentationName, 0)
      IF----data.instrumentationName == null, ii = null

    • IF---- ii!=null ----

      ​ final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
      ​ appContext.getClassLoader(), false, true, false);
      ​ final ContextImpl instrContext = ContextImpl.createAppContext(this, pi)

      ELSE ----
      mInstrumentation = new Instrumentation();

      END IF;

    • instrApp.initForUser(UserHandle.myUserId());
      final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
      appContext.getClassLoader(), false, true, false);

    • final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);

    • Application app = data.info.makeApplication(data.restrictedBackupMode, null)

      IF--------如果LoadedApk的mApplication中不为空就返回mApplication,
      ELSE ---如果为空就

      先得到String appClass = mApplicationInfo.className;
      再获取java.lang.ClassLoader cl = getClassLoader();
      再创建ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this)
      最终通过app = mActivityThread.mInstrumentation.newApplication(
      cl, appClass, appContext)创建,
      END IF-----

    • mInstrumentation.callApplicationOnCreate(app);

      app.onCreate()

    • 最后我们返回ActivityManagerService.attachApplicationLocked()继续往下

  5. mStackSupervisor.attachApplicationLocked(app)
    // //ActivityStackSupervisor.java
    // 来自ActivityManagerService.attachApplicationLocked(thread, callingPid, callingUid, startSeq)

  6. ---->realStartActivityLocked(activity, app, top == activity /* andResume /, true / checkConfig */)
    //ActivityStackSupervisor.java

  7. mService.getLifecycleManager().scheduleTransaction(clientTransaction)
    // ActivityManagerService.java --- mService
    // ClientLifecycleManager.java --- mService.getLifecycleManager()
    // final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken);
    // 在ActivityStackSupervisor.realStartActivityLocked()方法内部构造
    // ClientLifecycleManager.scheduleTransaction(ClientTransaction transaction)

  8. mLifecycleManager.scheduleTransaction(ClientTransaction transaction)
    // ClientLifecycleManager.java

  9. transaction.schedule()
    // ClientTransaction.java

  10. mClient.scheduleTransaction(this)

    //ApplicationThread.java

  11. ActivityThread.this.scheduleTransaction(transaction);

  12. ClientTransactionHandler.scheduleTransaction(transaction)
    // ActivityThread extends ClientTransactionHandler

  13. sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);

    // ClientTransactionHandler.java

  14. handleMessage(Message msg)
    // ActivityThread.H.

  15. mTransactionExecutor.execute(transaction);
    //final ClientTransaction transaction = (ClientTransaction) msg.obj;
    // TransactionExecutor.java 是ActivityThread的属性,定义时就初始化了
    // private TransactionExecutor mTransactionExecutor = new TransactionExecutor(this)

  16. executeCallbacks(transaction);
    // TransactionExecutor.java

    1. final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
  17. item.execute(mTransactionHandler, token, mPendingActions);

    //LaunchActivityItem.java

    //在ActivityStackSupervisor的realStartActivityLocked()方法构造transaction
    

    ​ //构造clientTransaction后将LaunchActivityItem添加入Callbacks

    ​ //最后后作为sendMessage参数传递过来

    ​ //在handleMessage方法中做了转换

     final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
             r.appToken);
     clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
             System.identityHashCode(r), r.info,
             // TODO: Have this take the merged configuration instead of separate global
             // and override configs.
             mergedConfiguration.getGlobalConfiguration(),
             mergedConfiguration.getOverrideConfiguration(), r.compat,
             r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
             r.persistentState, results, newIntents, mService.isNextTransitionForward(),
             profilerInfo));
    
  18. client.handleLaunchActivity(r, pendingActions, null /* customIntent */);

  19. //ActivityStackSupervisor.realStartActivityLocked()内

  20. client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    因为ActivityThread extends ClientTransactionHandler且ActivityThread 覆写了此方法

  21. final Activity a = performLaunchActivity(r, customIntent)
    // ActivityThread.Java

    • ComponentName component = r.intent.getComponent()

    • 新建ContextImpl appContext = createBaseContextForActivity(r)

    • 通过 mInstrumentation.newActivity(cl, component.getClassName(), r.intent)创建 Activity

      /frameworks/base/java/android/app/Instrumentation.java

      getFactory(pkg).instantiateActivity(cl, className, intent)

      1. getFactory(pkg)

      ​ LoadedApk apk = mThread.peekPackageInfo(pkg, true); apk.getAppFactory()

      ​ LoadedApk构造时创建了AppComponentFactory

      1. AppComponentFactory.instantiateActivity(cl, className, intent)

      ​ 最终通过classloader加载类,然后newInstance()

    • Application app = r.packageInfo.makeApplication(false, mInstrumentation)

      IF--------如果LoadedApk的mApplication中不为空就返回mApplication,
      ELSE ---如果为空就

      先得到String appClass = mApplicationInfo.className;
      再获取java.lang.ClassLoader cl = getClassLoader();
      再创建ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this)
      最终通过app = mActivityThread.mInstrumentation.newApplication(
      cl, appClass, appContext)创建,
      END IF-----

    • 调用Acitivity的attach方法
      activity.attach(appContext, this, getInstrumentation(), r.token,
      r.ident, app, r.intent, r.activityInfo, title, r.parent,
      r.embeddedID, r.lastNonConfigurationInstances, config,
      r.referrer, r.voiceInteractor, window, r.configCallback);
      Activity extends ContextThemeWrapper
      ContextThemeWrapper extends ContextWrapper
      ContextWrapper extends Context
      Activity的attach()方法通过attachBaseContext一层一层往上调用传递

    • mInstrumentation.callActivityOnCreate(activity....)传入activity最终调用acitivity的onCreate方法

      r.isPersistable()是否持久模式重启
      IF--true---ImInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
      ELSE------mInstrumentation.callActivityOnCreate(activity, r.state);

      正常我们走else

      END IF----activity.performCreate(icicle, persistentState)

      最终都会activity.performCreate(Bundle icicle, PersistableBundle persistentState),只是最后一个参数有可能空
      activity.onCreate(icicle)
      我们在activity中setContentView(R.layout.activity_main);加载我们的布局

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

推荐阅读更多精彩内容