Android系统源码分析--Zygote和SystemServer启动过程

按计划本来从这章开始写四大组件的启动过程的,但是看看源码结构发现为了说的更明白还是先写一点系统framework层启动的内容,帮助理解四大组件的启动以及管理过程。我们知道四大组件管理是通过一些服务以及线程实现的,所以先把一些基本概念弄清楚比较好,比如AMS(ActivityManagerService)、PMS(PackageManagerService)等系统服务的作用以及调用方式,了解这些之后再看四大组件相对容易些,因此我们本章先介绍系统启动、部分系统服务的作用。

Zygote启动过程

Zygote是一个孕育器,Android系统所有的应用进程以及系统服务SystemServer都是有Zygote进程孕育(fork)而生的,因此Zygote在Android启动过程中起着决定作用。Zygote的启动是从它的main函数开始的,因此我们从这个函数开始分析。整个过程看下面的时序图。

Zygote.jpg

下面我们开始根据时序图进行分析。

Step 0.ZygoteInit.main

    public static void main(String argv[]) {
        ...
        try {
            ...

            registerZygoteSocket(socketName);
            
            ...
            
            preload();
            
            ...

            gcAndFinalize();
            
            ...

            if (startSystemServer) {
                startSystemServer(abiList, socketName);
            }

            runSelectLoop(abiList);

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            ...
        } catch (Throwable ex) {
            ...
        }
    }

首先调用registerZygoteSocket方法,创建一个socket接口,用来和ActivityManagerService通讯,然后调用preload方法预加载一些资源等;然后调用gcAndFinalize方法释放一些内存;然后调用startSystemServer方法启动SystemServer组件,然后调用runSelectLoop方法,创建一个无限循环,在socket接口上等待ActivityManagerService请求创建新的应用程序进程;最后调用closeServerSocket方法关闭上面创建的socket。

Step 1.ZygoteInit.registerZygoteSocket

   private static void registerZygoteSocket(String socketName) {
        if (sServerSocket == null) {
            int fileDesc;
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
            try {
                String env = System.getenv(fullSocketName);
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) {
                ...
            }

            try {
                FileDescriptor fd = new FileDescriptor();
                fd.setInt$(fileDesc);
                sServerSocket = new LocalServerSocket(fd);
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
    }

这个sServerSocket是通过传入FileDescriptor(文件描述者)通过new一个来LocalServerSocket创建的。

Step 2.LocalServerSocket

    public LocalServerSocket(FileDescriptor fd) throws IOException
    {
        impl = new LocalSocketImpl(fd);
        impl.listen(LISTEN_BACKLOG);
        localAddress = impl.getSockAddress();
    }

在LocalServerSocket构造函数中又new了一个LocalSocketImpl,然后调用LocalSocketImpl的listen方法,最后通过getSockAddress方法获取LocalSocketAddress对象。

Step 3.LocalSocketImpl

    /*package*/ LocalSocketImpl(FileDescriptor fd) throws IOException
    {
        this.fd = fd;
    }

这里只是传入了FileDescriptor(文件描述者)。

Step 5.ZygoteInit.preload

    static void preload() {
        ...
        beginIcuCachePinning();
        ...
        preloadClasses();
        ...
        preloadResources();
        ...
        preloadOpenGL();
        ...
        preloadSharedLibraries();
        preloadTextResources();
        ...
    }

这里主要是预加载,1.预加载ICU缓存,2.执行Zygote进程初始化,预加载一些普通类,3.预加载mResources,4.预加载OpenGL,5.预加载共享库,6.预加载TextView的字体缓存。

Step 12.ZygoteInit.gcAndFinalize

    /*package*/ static void gcAndFinalize() {
        final VMRuntime runtime = VMRuntime.getRuntime();
        ...
        System.gc();
        runtime.runFinalizationSync();
        System.gc();
    }

这里主要是调用System.gc来释放一部分内存。

Step 13.ZygoteInit.startSystemServer

    private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
        ...

        int pid;

        try {
            ...

            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            ...
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

首先Zygote会通过调用Zygote.forkSystemServer方法来创建一个新的进程来启动SystemServer,并且返回这个进程的pid,如果pid为0,并且有另外一个Zygote则会执行waitForSecondaryZygote关闭另外的Zygote进程,然后调用handleSystemServerProcess方法。

Step 16.ZygoteInit.handleSystemServerProcess

    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

        closeServerSocket();

        ...

        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if (systemServerClasspath != null) {
            performSystemServerDexOpt(systemServerClasspath);
        }

        if (parsedArgs.invokeWith != null) {
            ...
        } else {
            ...
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }
    }

首先调用closeServerSocket方法关闭socket,然后调用performSystemServerDexOpt来创建安装连接InstallerConnection,最后调用RuntimeInit.zygoteInit方法。

Step 19.RuntimeInit.zygoteInit

    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        ...
        nativeZygoteInit();
        applicationInit(targetSdkVersion, argv, classLoader);
    }

首先调用nativeZygoteInit函数来执行一个Binder进程间通讯机制初始化工作,然后就可以在进程间进行通讯了,然后执行applicationInit方法。

Step 21.RuntimeInit.applicationInit

    private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        ...
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }

这里主要是执行一个invokeStaticMain方法来调用SystemServer的main方法。

Step 24.ZygoteInit.runSelectLoop

    private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        while (true) {
            ...
            try {
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                ...
            }
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    boolean done = peers.get(i).runOnce();
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }

这里通过acceptCommandPeer来创建ActivityManagerService与Socket的连接,然后调用ZygoteConnection.runOnce方法来创建新的应用程序。

SystemServer启动过程

我们从上面的Step 13 知道了SystemServer的main函数调用位置,下面我们分析一下SystemServer的启动过程。

SystemServer.jpg

在main方法中new了一个SystemServer然后调用它的run方法:

   private void run() {
        try {
            ...

            // Mmmmmm... more memory!
            // 清除vm内存增长上限,由于启动过程需要较多的虚拟机内存空间
            VMRuntime.getRuntime().clearGrowthLimit();

            // The system server has to run all of the time, so it needs to be
            // as efficient as possible with its memory usage.
            // 设置内存的可能有效使用率为0.8
            VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

            // Some devices rely on runtime fingerprint generation, so make sure
            // we've defined it before booting further.
            Build.ensureFingerprintProperty();

            // Within the system server, it is an error to access Environment paths without
            // explicitly specifying a user.
            // 访问环境变量前,需要明确地指定用户
            Environment.setUserRequired(true);

            // Within the system server, any incoming Bundles should be defused
            // to avoid throwing BadParcelableException.
            BaseBundle.setShouldDefuse(true);

            // Ensure binder calls into the system always run at foreground priority.
            // 确保当前系统进程的binder调用,总是运行在前台优先级(foreground priority)
            BinderInternal.disableBackgroundScheduling(true);

            // Increase the number of binder threads in system_server
            BinderInternal.setMaxThreads(sMaxBinderThreads);

            ...

            // 准备主线程的Looper
            Looper.prepareMainLooper();

            // Initialize native services.
            // 加载android_servers.so库,该库包含的源码在frameworks/base/services/目录下
            System.loadLibrary("android_servers");

            // Check whether we failed to shut down last time we tried.
            // This call may not return.
            performPendingShutdown();

            // Initialize the system context.
            // 初始化系统上下文
            createSystemContext();

            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            //将mSystemServiceManager添加到本地服务的成员sLocalServiceObjects
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        } finally {
            ...
        }

        // Start services.
        try {
            ...
            startBootstrapServices(); // 启动引导服务
            startCoreServices();      // 启动核心服务
            startOtherServices();     // 启动其他服务
        } catch (Throwable ex) {
            ...
        } finally {
            ...
        }

        ...

        // Loop(循环) forever.
        Looper.loop();
        ...
    }

Step 3.Build.ensureFingerprintProperty

    public static void ensureFingerprintProperty() {
        if (TextUtils.isEmpty(SystemProperties.get("ro.build.fingerprint"))) {
            try {
                SystemProperties.set("ro.build.fingerprint", FINGERPRINT);
            } catch (IllegalArgumentException e) {
                Slog.e(TAG, "Failed to set fingerprint property", e);
            }
        }
    }

确认设备的指纹属性。

Step 7.Looper.prepareMainLooper()

    public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }

准备main looper,这个详细的过程我们下一章再讲,这里先看一下流程。

Step 10.SystemServer.performPendingShutdown

    private void performPendingShutdown() {
        final String shutdownAction = SystemProperties.get(
                ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
        if (shutdownAction != null && shutdownAction.length() > 0) {
            // 是否重启
            boolean reboot = (shutdownAction.charAt(0) == '1');

            final String reason;
            if (shutdownAction.length() > 1) {
                reason = shutdownAction.substring(1, shutdownAction.length());
            } else {
                reason = null;
            }

            if (PowerManager.REBOOT_RECOVERY_UPDATE.equals(reason)) {
                File packageFile = new File(UNCRYPT_PACKAGE_FILE);
                if (packageFile.exists()) {
                    String filename = null;
                    try {
                        filename = FileUtils.readTextFile(packageFile, 0, null);
                    } catch (IOException e) {
                        Slog.e(TAG, "Error reading uncrypt package file", e);
                    }

                    if (filename != null && filename.startsWith("/data")) {
                        if (!new File(BLOCK_MAP_FILE).exists()) {
                            ...
                            return;
                        }
                    }
                }
            }
            ShutdownThread.rebootOrShutdown(null, reboot, reason);
        }
    }

这里主要是通过关机的action来判断是否重启或者关机。

Step 13.SystemServer.createSystemContext

    private void createSystemContext() {
        // 初始化ActivityThread,并设置默认主题
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
    }

首先调用ActivityThread.systemMain方法创建ActivityThread对象然后获取mSystemContext,并且设置默认系统主题。

Step 15.ActivityThread.systemMain

    public static ActivityThread systemMain() {
        ...
        ActivityThread thread = new ActivityThread();
        thread.attach(true);
        return thread;
    }

创建ActivityThread对象,并调用attach方法。

Step 17.ResourcesManager.getInstance

    public static ResourcesManager getInstance() {
        synchronized (ResourcesManager.class) {
            if (sResourcesManager == null) {
                sResourcesManager = new ResourcesManager();
            }
            return sResourcesManager;
        }
    

单例模式创建ResourcesManager对象并且返回。

Step 19.ActivityThread.attach

    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ...
        } else {
            ...
            try {
                mInstrumentation = new Instrumentation();
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
                ...
            }
        }

        ...
    }

因为参数传入的是true,表明是系统的线程,所以执行else里面的内容,首先创建Instrumentation,然后调用ContextImpl.createAppContext方法创建ContextImpl,然后通过调用LoadedApk.makeApplication方法创建Application,然后调用Application.onCreate方法。

Step 22.ContextImpl.createAppContext

    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
        return new ContextImpl(null, mainThread,
                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
    }

通过new ContextImpl来创建ContextImpl对象。

Step 22.LoadedApk.makeApplication

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        ...

        Application app = null;

        ...

        try {
            ...
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            ...
        }
        ...

        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ...
            }
        }

        ...

        return app;
    }

通过ContextImpl.createAppContext方法创建ContextImpl对象,然后调用mActivityThread.mInstrumentation.newApplication方法创建Application对象,然后调用instrumentation.callApplicationOnCreate方法。

Step 23.ContextImpl.createAppContext

    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
        return new ContextImpl(null, mainThread,
                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
    }

创建ContextImpl对象并返回。

Step 26.Instrumentation.createAppContext

    public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        return newApplication(cl.loadClass(className), context);
    }

这里主要是调用newApplication方法返回Application。

Step 28.Instrumentation.newApplication

    static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }

调用class.newInstance方法创建Application,然后调用Application.attach方法,向Application中传入context。

Step 32.Application.attach

    /* package */ final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }

通过ContextImpl.getImpl方法获取LoadedApk对象。

Step 34.Instrumentation.callApplicationOnCreate

    public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }

这里开始调用Application的onCreate方法。

Step 39.ActivityThread.getSystemContext

    public ContextImpl getSystemContext() {
        synchronized (this) {
            if (mSystemContext == null) {
                mSystemContext = ContextImpl.createSystemContext(this);
            }
            return mSystemContext;
        }
    }

通过ContextImpl.createSystemContext创建mSystemContext。

Step 40.ContextImpl.createSystemContext

    static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread,
                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetrics());
        return context;
    }

创建ContextImpl并且返回。

Step 43.SystemServer.startBootstrapServices

    private void startBootstrapServices() {
        ...
        // 安装服务
        Installer installer = mSystemServiceManager.startService(Installer.class);

        // Activity管理服务
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);

        ...
        // 电量管理服务
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

        ...

        // 管理LEDs和背光灯服务
        mSystemServiceManager.startService(LightsService.class);

        // 显示管理服务
        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

        // 包管理服务
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();
        ...
        // 启动用户管理服务
        mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

        //初始化安装包资源的属性缓存
        AttributeCache.init(mSystemContext);

        // 启动系统进程的应用实例
        mActivityManagerService.setSystemProcess();

        // 启动传感器服务
        startSensorService();
    }

这里主要是启动系统引导服务。

Step 44.SystemServer.startCoreServices

    private void startCoreServices() {
        // 启动电池服务
        mSystemServiceManager.startService(BatteryService.class);

        // 启动应用统计服务
        mSystemServiceManager.startService(UsageStatsService.class);
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));

        // 启动WebView更新服务
        mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
    }

启动核心服务。

Step 45.SystemServer.startOtherServices

这里代码就不贴了,都是启动服务的代码,这里有很多服务,我简单列一下服务并说一下服务基本功能。

服务 名称 服务 名称
SchedulingPolicyService CameraService
TelecomLoaderService AccountManagerService.Lifecycle
ContentService.Lifecycle VibratorService
ConsumerIrService AlarmManagerService
InputManagerService WindowManagerService
VrManagerService PersistentDataBlockService
MetricsLoggerService IpConnectivityMetrics
PinnerService InputMethodManagerService.Lifecycle
MountService.Lifecycle UiModeManagerService
LockSettingsService.Lifecycle BluetoothService
DeviceIdleController NsdService
StatusBarManagerService ClipboardService
NetworkManagementService WifiService
NetworkScoreService NetworkStatsService
NetworkPolicyManagerService WifiNanService
WifiP2pService TextServicesManagerService.Lifecycle
WifiScanningService ConnectivityService
RttService DevicePolicyManagerService.Lifecycle
UpdateLockService RecoverySystemService
NotificationManagerService DeviceStorageMonitorService
LocationManagerService CountryDetectorService
SearchManagerService.Lifecycle DropBoxManagerService
AudioService.Lifecycle DockObserver
ThermalObserver MidiService.Lifecycle
UsbService.Lifecycle SerialService
HardwarePropertiesManagerService NightDisplayService
JobSchedulerService SoundTriggerService
BackupManagerService.Lifecycle AppWidgetService
VoiceInteractionManagerService GestureLauncherService
SensorNotificationService ContextHubSystemService
DiskStatsService SamplingProfilerService
NetworkTimeUpdateService CommonTimeManagementService
EmergencyAffordanceService DreamManagerService
AssetAtlasService GraphicsStatsService
PrintManagerService RestrictionsManagerService
MediaSessionService HdmiControlService
TvInputManagerService MediaResourceMonitorService
TvRemoteService MediaRouterService
TrustManagerService FingerprintService
ShortcutService.Lifecycle LauncherAppsService
MediaProjectionManagerService WearBluetoothService
WearWifiMediatorService WearTimeService
MmsServiceBroker RetailDemoModeService
NsdService WallpaperManagerService.Lifecycle

参考:

Android系统启动-SystemServer下篇
Android系统进程Zygote启动过程的源代码分析

原文地址:Android系统源码分析--Zygote和SystemServer启动过程

注:本文原创,转载请注明出处,多谢。

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

推荐阅读更多精彩内容