寫給Android開(kāi)發(fā)者的HarmonyOS入門指南

BANNER.jpg

前言

2023華為開(kāi)發(fā)者大會(huì) 之后聂使,HarmonyOS 后續(xù)版本將不再支持 Android應(yīng)用 的說(shuō)法愈演愈烈屯伞,雖然網(wǎng)絡(luò)上有很多相關(guān)的新聞,但大多都是基于 HarmonyOS NEXT 開(kāi)發(fā)者預(yù)覽版 不支持 Android應(yīng)用 安裝做的推測(cè)颅湘,目前未見(jiàn)華為官方正式發(fā)布說(shuō)明蕊苗。

也有人說(shuō)目前的鴻蒙開(kāi)發(fā)工具 DevEco Studio 里面都沒(méi)有集成 Android SDK,但這也只能說(shuō)明原生的鴻蒙應(yīng)用無(wú)法安裝在 Android 系統(tǒng)上刽锤,這個(gè)說(shuō)法尚未定論镊尺。

但是 HarmonyOS 的發(fā)展是必然的,作為移動(dòng)端的從業(yè)人員并思,自然不能停滯不前庐氮,今天我們就來(lái)走進(jìn) HarmonyOS 的世界。

準(zhǔn)備及注意

這篇文章是面向 Android開(kāi)發(fā)者 的宋彼,因此一些基本的東西我就不再贅述弄砍,相關(guān)文檔可以在華為開(kāi)發(fā)者聯(lián)盟查看。

以下內(nèi)容都是基于已經(jīng)搭建好 HarmonyOS 開(kāi)發(fā)環(huán)境(DevEco Studio输涕、HarmonyOS SDK)音婶;

DevEco Studio應(yīng)用簽名是和華為賬號(hào)綁定的,所以開(kāi)始前需要注冊(cè)一個(gè)華為賬號(hào)(首次運(yùn)行失敗會(huì)有提示)莱坎;

運(yùn)行 HarmonyOS 項(xiàng)目需要一部鴻蒙系統(tǒng)的手機(jī)衣式;(目前僅Mate 50、60系列手機(jī)能正常使用型奥,其它機(jī)型需要使用投屏工具進(jìn)行操作瞳收,直接在手機(jī)上操作會(huì)卡死)碉京;

讓我們從Hello World開(kāi)始

DevEco Studio

Android 開(kāi)發(fā)要使用 Android Studio 開(kāi)發(fā)厢汹,HarmonyOS 也提供了一個(gè) DevEco Studio 開(kāi)發(fā)工具,同樣是基于 IDEA 開(kāi)發(fā)的谐宙,因此功能界面和 Android Studio 大致相同烫葬,很容易上手,并且可以從 Import Sample 菜單里選擇官方提供的模板庫(kù)凡蜻,下載到本地運(yùn)行搭综。

工具下載地址:HUAWEI DevEco Studio和SDK下載和升級(jí) | 華為開(kāi)發(fā)者聯(lián)盟

WELCOME_TO_DEVECO_STUDIO.png

創(chuàng)建項(xiàng)目

點(diǎn)擊歡迎界面的 Create Project,創(chuàng)建新項(xiàng)目的流程也和 Android Studio 類似划栓,這里的 Ability UI組件類似 Android 中的 Activity兑巾,用于提供UI顯示及生命周期回調(diào),這里我們簡(jiǎn)單的用默認(rèn)模板創(chuàng)建一個(gè) Demo 項(xiàng)目忠荞;

CHOOSE_ABILITY_TEMPLATE.png

Bundle name 等同于 Android 中的 package name蒋歌,項(xiàng)目名帅掘、保存位置可以自選,其他配置保持默認(rèn)就可以了堂油,完成項(xiàng)目創(chuàng)建修档。

CONFIGURE_YOUR_PROJECT.png

項(xiàng)目結(jié)構(gòu)

待項(xiàng)目創(chuàng)建完成,你就能看到如下的項(xiàng)目目錄結(jié)構(gòu)府框,文件看上去很多吱窝,但是我們只需要關(guān)注重點(diǎn)部分;

PROJECT_FILE_TREE.png
  • Demo/build-profile.json5 項(xiàng)目配置文件迫靖,等同于 Android 項(xiàng)目中的 settings.gradle.kts

    {
      "app": {
        "signingConfigs": [], // 簽名配置
        "compileSdkVersion": 9, // SDK 版本配置
        "compatibleSdkVersion": 9, // SDK 版本配置
        "products": [
          {
            "name": "default",
            "signingConfig": "default",
          }
        ]
      },
      "modules": [ // 模塊配置
        {
          "name": "entry", // 模塊名
          "srcPath": "./entry", // 模塊路徑
          "targets": [
            {
              "name": "default",
              "applyToProducts": [
                "default"
              ]
            }
          ]
        }
      ]
    }
    
  • Demo/AppScope 存放全局資源及配置的路徑院峡;

  • Demo/AppScope/resources 應(yīng)用全局資源路徑;

  • Demo/AppScope/app.json5 應(yīng)用配置袜香,定義包名撕予、版本、應(yīng)用圖標(biāo)蜈首、名稱等配置:

    {
      "app": {
        "bundleName": "com.sample.demo", // 包名
        "vendor": "example", // 供應(yīng)商
        "versionCode": 1000000, // 版本號(hào)
        "versionName": "1.0.0", // 版本名
        "icon": "$media:app_icon", // 應(yīng)用圖標(biāo)实抡,此處配置影響應(yīng)用管理中顯示
        "label": "$string:app_name" // 應(yīng)用名,此處配置影響應(yīng)用管理中顯示
      }
    }
    

    使用的圖標(biāo):

    app_icon.png

名稱資源:

    {
      "string": [
        {
          "name": "app_name",
          "value": "Demo"
        }
      ]
    }

在應(yīng)用管理中顯示:

DEMO_IN_APP_SETTING.png
  • Demo/entry 應(yīng)用主模塊欢策,應(yīng)用入口吆寨,存放代碼、資源的路徑踩寇;

  • Demo/entry/src/main/module.json5 模塊配置文件啄清,類似 Android 項(xiàng)目中的 AndroidManifest.xml

    {
      "module": {
        "name": "entry", // 當(dāng)前module的名字,module打包成hap后俺孙,表示hap的名稱辣卒,標(biāo)簽值采用字符串表示(最大長(zhǎng)度31個(gè)字節(jié)),該名稱在整個(gè)應(yīng)用要唯一
        "type": "entry", // 表示模塊的類型睛榄,類型有三種荣茫,分別是entry、feature和har
        "srcEntry": "./ets/DemoAbilityStage.ts", // 模塊的入口文件路徑场靴,默認(rèn)沒(méi)有啡莉,需要手動(dòng)創(chuàng)建,類似 Android 中的 Application
        "description": "$string:module_desc", // 當(dāng)前模塊的描述信息
        "mainElement": "EntryAbility", // 該標(biāo)簽標(biāo)識(shí)hap的入口ability名稱或者extension名稱旨剥。只有配置為mainElement的ability或者extension才允許在服務(wù)中心露出
        "deviceTypes": [ // 該標(biāo)簽標(biāo)識(shí)hap可以運(yùn)行在哪類設(shè)備上
          "phone",
          "tablet"
        ],
        "deliveryWithInstall": true, // 該模塊是否隨應(yīng)用一起安裝
        "installationFree": false, // 釋放支持免安裝
        "pages": "$profile:main_pages", // ability 中使用的 page 信息配置
        "abilities": [ // ability 配置列表咧欣,類似 Android 中的 Activity 列表
          {
            "name": "EntryAbility", // 邏輯名,整個(gè)應(yīng)用要唯一
            "srcEntry": "./ets/entryability/EntryAbility.ts", // 入口代碼路徑
            "description": "$string:EntryAbility_desc", // 描述信息
            "icon": "$media:icon", // 圖標(biāo)轨帜,如果為 MainElement魄咕,必填,此處配置影響應(yīng)用列表顯示及任務(wù)棧顯示
            "label": "$string:EntryAbility_label", // 標(biāo)簽名蚌父,此處配置影響應(yīng)用列表顯示及任務(wù)棧顯示
            "startWindowIcon": "$media:icon", // 啟動(dòng)頁(yè)圖標(biāo)
            "startWindowBackground": "$color:start_window_background", // 啟動(dòng)頁(yè)背景顏色
            "exported": true,
            "skills": [
              {
                "entities": [
                  "entity.system.home"
                ],
                "actions": [
                  "action.system.home"
                ]
              }
            ]
          }
        ]
      }
    }
    

    使用的圖標(biāo):

icon.png

名稱資源:

    {
      "string": [
        {
          "name": "EntryAbility_label",
          "value": "Ability1"
        }
      ]
    }

在桌面顯示:

ABILITY_IN_DESKTOP.png

在任務(wù)棧顯示:

ABILITY_IN_STACK.png
如果有多個(gè) `UIAbility`哮兰,則配置了 `skills` 為 `entity.system.home` 的都會(huì)在桌面創(chuàng)建圖標(biāo):

    "skills": [
        {
            "entities": [
                "entity.system.home"
            ],
            "actions": [
                "action.system.home"
            ]
        }
    ]
  • Demo/entry/src/main/ets 源碼文件路徑烟具;

  • Demo/entry/src/main/ets/entryability/EntryAbility.ts UI 組件,類似 Android 中的 Activity奠蹬;

  • Demo/entry/src/main/resources 資源文件路徑朝聋;

項(xiàng)目架構(gòu)及與Android對(duì)比

從總體的項(xiàng)目架構(gòu)來(lái)看,HarmonyOS 項(xiàng)目是比較貼近 Android 項(xiàng)目中 Compose + 單Activity 架構(gòu)的囤躁,并且我們?cè)?HarmonyOS 中也能找到一些與 Android 項(xiàng)目對(duì)應(yīng)的關(guān)系:

Android HarmonyOS
settings.gradle.kts 項(xiàng)目配置文件 Demo/build-profile.json5 項(xiàng)目配置文件冀痕,不同的是將應(yīng)用的簽名、SDK版本狸演、多渠道配置移動(dòng)到了這里
build.gradle.kts 模塊配置文件 Demo/AppScope/app.json5 應(yīng)用配置文件言蛇,配置包名、版本宵距、圖標(biāo)腊尚、名稱
AndroidManifest.xml 清單文件 Demo/entry/src/main/module.json5 模塊配置文件,配置應(yīng)用入口满哪、路由等信息
Application 應(yīng)用程序入口 AbilityStage 應(yīng)用程序入口
Activity UI組件 UIAbility UI組件
Navgation 頁(yè)面路由 pages 頁(yè)面路由

生命周期

module.json5 中的 module 節(jié)點(diǎn)聲明 srcEntry婿斥,我們也能和 Android 應(yīng)用一樣配置一個(gè)全局的應(yīng)用程序入口,擁有類似的生命周期方法回調(diào):

import AbilityStage from '@ohos.app.ability.AbilityStage';

export default class DemoAbilityStage extends AbilityStage {
    
    onCreate() {
        // 應(yīng)用啟動(dòng)回調(diào)
    }
}

HarmonyOS 中的UI組件 UIAbility 也和 Android 中的 Activity 有著類似的生命周期:

import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {
  onCreate(want, launchParam) {
    // 組件創(chuàng)建
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }

  onDestroy() {
    // 組件銷毀
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage) {
    // window 創(chuàng)建
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    // 設(shè)置布局哨鸭,顯示 ets/pages/Index.ets 的布局
    windowStage.loadContent('pages/Index', (err, data) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
    });
  }

  onWindowStageDestroy() {
    // window 銷毀
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground() {
    // 進(jìn)入前臺(tái)
    // Ability has brought to foreground
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground() {
    // 進(jìn)入后臺(tái)
    // Ability has back to background
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }
}

HarmonyOSUIAbility 沒(méi)有 AndroidActivityonResume onPause 生命周期回調(diào)方法民宿,當(dāng)然如果需要的話還是有方案可以實(shí)現(xiàn)的,需要在 onWindowStageCreate 方法里像鸡,通過(guò) windowStage 實(shí)現(xiàn):

onWindowStageCreate(windowStage: window.WindowStage) {
    windowStage.on('windowStageEvent', (event) => {
        // event 取值為枚舉類型 window.WindowStageEventType
        if(event === window.WindowStageEventType.ACTIVE) {
            // 獲取焦點(diǎn)
        } else {
            // 失去焦點(diǎn)
        }
    })
}

布局

HarmonyOS 使用 ArkTS 作為開(kāi)發(fā)語(yǔ)言活鹰,并且提供 ArkTS UI 組件用于UI布局,就像上面 UIAbility 中顯示的布局 ets/pages/Index.ets

@Entry // 聲明這個(gè)組件可作為頁(yè)面入口只估,即在 UIAbility 中加載或進(jìn)行頁(yè)面跳轉(zhuǎn)
@Component // 聲明這是一個(gè)UI組件
struct Index {
  @State message: string = 'Hello World'

  build() {
    // 聲明布局
    Row() { // 橫向布局
      Column() { // 豎向布局
        Text(this.message) // 文本控件
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%') // 寬度鋪滿
    }
    .height('100%') // 高度鋪滿
  }
}
INDEX_PREVIEW_1.png

上面是新建項(xiàng)目默認(rèn)生成的布局志群,效果是在屏幕中間顯示 Hello World 文本,更多組件可參考組件參考(基于ArkTS的聲明式開(kāi)發(fā)范式蛔钙。

界面跳轉(zhuǎn)

Pages 跳轉(zhuǎn)

HarmonyOS 生成的項(xiàng)目里锌云,默認(rèn)只有一個(gè) UIAbility,并通過(guò) windowStage.loadContent 來(lái)加載顯示布局夸楣,因此一種多界面的方式就是編寫不同的 Page宾抓,在不同的 Page 直接跳轉(zhuǎn)子漩;

首先豫喧,我們?cè)?ets/pages 路徑下新建一個(gè) Second.ets 文件,并參照 Index.ets 聲明布局幢泼,并添加按鈕用于返回上一級(jí):

import router from '@ohos.router'

@Entry
@Component
struct Second {
  @State message: string = 'Second Page'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        // 添加按鈕
        Button("點(diǎn)擊返回")
          .onClick(() => {
            // 按鈕點(diǎn)擊通過(guò) router 返回上一級(jí)
            router.back()
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

然后紧显,我們需要在 resources/base/profile/main_pages.json 文件中添加這個(gè)界面的聲明:

{
  "src": [
    "pages/Index",
    "pages/Second"
  ]
}

在之前的 Index.ets 布局中添加按鈕并配置點(diǎn)擊跳轉(zhuǎn)邏輯:

import router from '@ohos.router'

@Entry
@Component
struct Index {
  @State message: string = 'Hello World'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        // 添加按鈕
        Button("點(diǎn)擊跳轉(zhuǎn)")
          .onClick(() => {
            // 按鈕點(diǎn)擊通過(guò) router 跳轉(zhuǎn)到 pages/Second
            router.pushUrl({
              url: "pages/Second"
            })
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

這樣通過(guò)點(diǎn)擊按鈕就能進(jìn)行界面的跳轉(zhuǎn)了。上面創(chuàng)建 Page 的方式推薦在 ets/pages 路徑使用 New -> Page 進(jìn)行創(chuàng)建缕棵,會(huì)自動(dòng)生成對(duì)應(yīng)的布局文件和配置孵班,更便捷且不容易出錯(cuò)涉兽。

ROUTE_PAGE.gif

UIAbility 跳轉(zhuǎn)

雖然 HarmonyOS 官方提供的模板里面都只有一個(gè) UIAbility,但是它還是支持多 UIAbility 的篙程;

同樣的在 ets 路徑下參照 EntryAbility.ts 創(chuàng)建一個(gè)新的 SecondEntryAbility.ts枷畏,在 onWindowStageCreate 中加載布局 pages/SecondAblity,在 module.json5 中添加對(duì)應(yīng)的配置即可虱饿,這里還是推薦使用 New -> Ability 進(jìn)行創(chuàng)建拥诡;

ets/pages/SecondAbility.ets 中修改文本及添加返回按鈕:

import common from '@ohos.app.ability.common'

@Preview
@Entry
@Component
struct SecondAbility {
  @State message: string = 'Second Ability'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Button("點(diǎn)擊返回")
          .margin({ top: 30 })
          .onClick(() => {
            // 按鈕點(diǎn)擊關(guān)閉當(dāng)前 UIAbility
            let context = getContext(this) as unknown as common.UIAbilityContext
            context.terminateSelf()
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

然后我們修改 ets/pages/Index.ets 中的代碼,在之前的按鈕下方添加一個(gè)新的按鈕點(diǎn)擊跳轉(zhuǎn) SecondEntryAbility

import common from '@ohos.app.ability.common'
import Want from '@ohos.app.ability.Want'

@Entry
@Component
struct Index {
  @State message: string = 'Hello World'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Button("點(diǎn)擊跳轉(zhuǎn)")
          .onClick(() => {
            // 按鈕點(diǎn)擊跳轉(zhuǎn)到 SecondEntryAbility
            let context = getContext(this) as unknown as common.UIAbilityContext
            let want: Want = {
              deviceId: "",
              bundleName: "com.sample.demo",
              abilityName: "SecondEntryAbility",
            }
            context.startAbility(want)
          })
        // 添加按鈕
        Button("點(diǎn)擊跳轉(zhuǎn)Ability")
          .onClick(() => {
            // 按鈕點(diǎn)擊跳轉(zhuǎn)到 SecondEntryAbility
            let context = getContext(this) as unknown as common.UIAbilityContext
            let want: Want = {
              deviceId: "",
              bundleName: "com.sample.demo",
              abilityName: "SecondEntryAbility",
            }
            context.startAbility(want)
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

這里我們就要提到 UIAbilityActivity 的區(qū)別了氮发,雖然他們同樣都是UI組件渴肉,但是在 HarmonyOS 中,每打開(kāi)一個(gè) UIAbility爽冕,都會(huì)在任務(wù)棧中單獨(dú)顯示出來(lái)仇祭;

START_ABILITY.gif

總結(jié)

一路看下來(lái),相信你對(duì) HarmonyOS 項(xiàng)目如何上手已經(jīng)有了思路颈畸,作為 Android 開(kāi)發(fā)者乌奇,我在寫這篇文章的時(shí)候更多的是在尋找 HarmonyOSAndroid 開(kāi)發(fā)的相似之處,通過(guò)這樣的對(duì)比眯娱,我們不需要從頭了解 HarmonyOS 開(kāi)發(fā)华弓,就能更快的入手了。

文章作者: WangJie0822

文章鏈接: http://www.wangjie0822.top/posts/b8dc3748

版權(quán)聲明: 本博客所有文章除特別聲明外困乒,均采用 CC BY-NC-SA 4.0 許可協(xié)議寂屏。轉(zhuǎn)載請(qǐng)注明來(lái)自 WangJie0822

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末娜搂,一起剝皮案震驚了整個(gè)濱河市迁霎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌百宇,老刑警劉巖考廉,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異携御,居然都是意外死亡昌粤,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門啄刹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)涮坐,“玉大人,你說(shuō)我怎么就攤上這事誓军「ざ铮” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵昵时,是天一觀的道長(zhǎng)捷雕。 經(jīng)常有香客問(wèn)我椒丧,道長(zhǎng),這世上最難降的妖魔是什么救巷? 我笑而不...
    開(kāi)封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任壶熏,我火速辦了婚禮,結(jié)果婚禮上浦译,老公的妹妹穿的比我還像新娘久橙。我一直安慰自己,他們只是感情好管怠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布淆衷。 她就那樣靜靜地躺著,像睡著了一般渤弛。 火紅的嫁衣襯著肌膚如雪祝拯。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天她肯,我揣著相機(jī)與錄音佳头,去河邊找鬼。 笑死晴氨,一個(gè)胖子當(dāng)著我的面吹牛康嘉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播籽前,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼亭珍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了枝哄?” 一聲冷哼從身側(cè)響起肄梨,我...
    開(kāi)封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挠锥,沒(méi)想到半個(gè)月后众羡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蓖租,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年粱侣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓖宦。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡齐婴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出球昨,到底是詐尸還是另有隱情尔店,我是刑警寧澤眨攘,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布主慰,位于F島的核電站嚣州,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏共螺。R本人自食惡果不足惜该肴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望藐不。 院中可真熱鬧匀哄,春花似錦、人聲如沸雏蛮。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)挑秉。三九已至法梯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間犀概,已是汗流浹背立哑。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留姻灶,地道東北人铛绰。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像产喉,于是被迫代替她去往敵國(guó)和親捂掰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355