Android之四大組件屠列、六大布局啦逆、五大存儲

一.四大組件:


Android四大組件分別為activity、service脸哀、content provider蹦浦、broadcast receiver。

一撞蜂、android四大組件詳解

1盲镶、activity

(1)一個Activity通常就是一個單獨的屏幕(窗口)。

(2)Activity之間通過Intent進行通信蝌诡。

(3)android應(yīng)用中每一個Activity都必須要在AndroidManifest.xml配置文件中聲明溉贿,否則系統(tǒng)將不識別也不執(zhí)行該Activity。

2浦旱、service

(1)service用于在后臺完成用戶指定的操作宇色。service分為兩種:

(a)started(啟動):當(dāng)應(yīng)用程序組件(如activity)調(diào)用startService()方法啟動服務(wù)時,服務(wù)處于started狀態(tài)颁湖。

(b)bound(綁定):當(dāng)應(yīng)用程序組件調(diào)用bindService()方法綁定到服務(wù)時宣蠕,服務(wù)處于bound狀態(tài)。

(2)startService()與bindService()區(qū)別:

(a)started service(啟動服務(wù))是由其他組件調(diào)用startService()方法啟動的甥捺,這導(dǎo)致服務(wù)的onStartCommand()方法被調(diào)用抢蚀。當(dāng)服務(wù)是started狀態(tài)時,其生命周期與啟動它的組件無關(guān)镰禾,并且可以在后臺無限期運行皿曲,即使啟動服務(wù)的組件已經(jīng)被銷毀榨惰。因此谴仙,服務(wù)需要在完成任務(wù)后調(diào)用stopSelf()方法停止,或者由其他組件調(diào)用stopService()方法停止梆惯。

(b)使用bindService()方法啟用服務(wù)备韧,調(diào)用者與服務(wù)綁定在了一起劫樟,調(diào)用者一旦退出,服務(wù)也就終止,大有“不求同時生毅哗,必須同時死”的特點听怕。

(3)開發(fā)人員需要在應(yīng)用程序配置文件中聲明全部的service,使用標(biāo)簽虑绵。

(4)Service通常位于后臺運行尿瞭,它一般不需要與用戶交互,因此Service組件沒有圖形用戶界面翅睛。Service組件需要繼承Service基類声搁。Service組件通常用于為其他組件提供后臺服務(wù)或監(jiān)控其他組件的運行狀態(tài)。

3捕发、content provider

(1)android平臺提供了Content Provider使一個應(yīng)用程序的指定數(shù)據(jù)集提供給其他應(yīng)用程序疏旨。其他應(yīng)用可以通過ContentResolver類從該內(nèi)容提供者中獲取或存入數(shù)據(jù)。

(2)只有需要在多個應(yīng)用程序間共享數(shù)據(jù)是才需要內(nèi)容提供者扎酷。例如檐涝,通訊錄數(shù)據(jù)被多個應(yīng)用程序使用,且必須存儲在一個內(nèi)容提供者中法挨。它的好處是統(tǒng)一數(shù)據(jù)訪問方式谁榜。

(3)ContentProvider實現(xiàn)數(shù)據(jù)共享。ContentProvider用于保存和獲取數(shù)據(jù)凡纳,并使其對所有應(yīng)用程序可見窃植。這是不同應(yīng)用程序間共享數(shù)據(jù)的唯一方式,因為android沒有提供所有應(yīng)用共同訪問的公共存儲區(qū)荐糜。

(4)開發(fā)人員不會直接使用ContentProvider類的對象巷怜,大多數(shù)是通過ContentResolver對象實現(xiàn)對ContentProvider的操作。

(5)ContentProvider使用URI來唯一標(biāo)識其數(shù)據(jù)集暴氏,這里的URI以content://作為前綴延塑,表示該數(shù)據(jù)由ContentProvider來管理。

4答渔、broadcast receiver

(1)你的應(yīng)用可以使用它對外部事件進行過濾页畦,只對感興趣的外部事件(如當(dāng)電話呼入時,或者數(shù)據(jù)網(wǎng)絡(luò)可用時)進行接收并做出響應(yīng)研儒。廣播接收器沒有用戶界面。然而独令,它們可以啟動一個activity或serice來響應(yīng)它們收到的信息端朵,或者用NotificationManager來通知用戶。通知可以用很多種方式來吸引用戶的注意力燃箭,例如閃動背燈冲呢、震動、播放聲音等招狸。一般來說是在狀態(tài)欄上放一個持久的圖標(biāo)敬拓,用戶可以打開它并獲取消息邻薯。

(2)廣播接收者的注冊有兩種方法,分別是程序動態(tài)注冊和AndroidManifest文件中進行靜態(tài)注冊乘凸。

(3)動態(tài)注冊廣播接收器特點是當(dāng)用來注冊的Activity關(guān)掉后厕诡,廣播也就失效了。靜態(tài)注冊無需擔(dān)憂廣播接收器是否被關(guān)閉营勤,只要設(shè)備是開啟狀態(tài)灵嫌,廣播接收器也是打開著的。也就是說哪怕app本身未啟動葛作,該app訂閱的廣播在觸發(fā)時也會對它起作用寿羞。

二、android四大組件總結(jié):

(1)4大組件的注冊

4大基本組件都需要注冊才能使用赂蠢,每個Activity绪穆、service、Content Provider都需要在AndroidManifest文件中進行配置虱岂。AndroidManifest文件中未進行聲明的activity玖院、服務(wù)以及內(nèi)容提供者將不為系統(tǒng)所見,從而也就不可用量瓜。而broadcast receiver廣播接收者的注冊分靜態(tài)注冊(在AndroidManifest文件中進行配置)和通過代碼動態(tài)創(chuàng)建并以調(diào)用Context.registerReceiver()的方式注冊至系統(tǒng)司恳。需要注意的是在AndroidManifest文件中進行配置的廣播接收者會隨系統(tǒng)的啟動而一直處于活躍狀態(tài),只要接收到感興趣的廣播就會觸發(fā)(即使程序未運行)绍傲。

(2)4大組件的激活

內(nèi)容提供者的激活:當(dāng)接收到ContentResolver發(fā)出的請求后扔傅,內(nèi)容提供者被激活。而其它三種組件activity烫饼、服務(wù)和廣播接收器被一種叫做intent的異步消息所激活猎塞。

(3)4大組件的關(guān)閉

內(nèi)容提供者僅在響應(yīng)ContentResolver提出請求的時候激活。而一個廣播接收器僅在響應(yīng)廣播信息的時候激活杠纵。所以荠耽,沒有必要去顯式的關(guān)閉這些組件。Activity關(guān)閉:可以通過調(diào)用它的finish()方法來關(guān)閉一個activity比藻。服務(wù)關(guān)閉:對于通過startService()方法啟動的服務(wù)要調(diào)用Context.stopService()方法關(guān)閉服務(wù)铝量,使用bindService()方法啟動的服務(wù)要調(diào)用Contex.unbindService()方法關(guān)閉服務(wù)。

(4)android中的任務(wù)(activity棧)

(a)任務(wù)其實就是activity的棧银亲,它由一個或多個Activity組成慢叨,共同完成一個完整的用戶體驗。棧底的是啟動整個任務(wù)的Activity务蝠,棧頂?shù)氖钱?dāng)前運行的用戶可以交互的Activity拍谐,當(dāng)一個activity啟動另外一個的時候,新的activity就被壓入棧,并成為當(dāng)前運行的activity轩拨。而前一個activity仍保持在棧之中践瓷。當(dāng)用戶按下BACK鍵的時候,當(dāng)前activity出棧亡蓉,而前一個恢復(fù)為當(dāng)前運行的activity晕翠。棧中保存的其實是對象,棧中的Activity永遠不會重排寸宵,只會壓入或彈出崖面。

(b)任務(wù)中的所有activity是作為一個整體進行移動的。整個的任務(wù)(即activity棧)可以移到前臺梯影,或退至后臺巫员。

(c)Android系統(tǒng)是一個多任務(wù)(Multi-Task)的操作系統(tǒng),可以在用手機聽音樂的同時甲棍,也執(zhí)行其他多個程序简识。每多執(zhí)行一個應(yīng)用程序,就會多耗費一些系統(tǒng)內(nèi)存感猛,當(dāng)同時執(zhí)行的程序過多七扰,或是關(guān)閉的程序沒有正確釋放掉內(nèi)存,系統(tǒng)就會覺得越來越慢陪白,甚至不穩(wěn)定颈走。為了解決這個問題,Android引入了一個新的機制咱士,即生命周期(Life Cycle)立由。

? ? 二.六大布局:

Android六大界面布局方式:

聲明Android程序布局有兩種方式:

1) 使用XML文件描述界面布局;

2) 在Java代碼中通過調(diào)用方法進行控制序厉。

我們既可以使用任何一種聲明界面布局的方式锐膜,也可以同時使用兩種方式。

使用XML文件聲明有以下3個特點:

1) 將程序的表現(xiàn)層和控制層分離弛房;

2) 在后期修改用戶界面時道盏,無須更改程序的源程序;

3) 可通過WYSIWYG可視化工具直接看到所設(shè)計的用戶界面文捶,有利于加快界面設(shè)計的過程荷逞。

建議盡量采用XML文件聲明界面元素布局。在程序運行時動態(tài)添加界面布局會大大降低應(yīng)用響應(yīng)速度粹排,但依然可以在必要時動態(tài)改變屏幕內(nèi)容颅围。

六大界面布局方式包括:?線性布局(LinearLayout)、框架布局(FrameLayout)恨搓、表格布局(TableLayout)、相對布局(RelativeLayout)、絕對布局(AbsoluteLayout)和網(wǎng)格布局(GridLayout)?斧抱。

1. LinearLayout線性布局

LinearLayout容器中的組件一個挨一個排列常拓,通過控制android:orientation屬性,可控制各組件是橫向排列還是縱向排列辉浦。

LinearLayout的常用XML屬性及相關(guān)方法

XML屬性相關(guān)方法說明

android:gravitysetGravity(int)設(shè)置布局管理器內(nèi)組件的對齊方式

android:orientationsetOrientation(int)設(shè)置布局管理器內(nèi)組件的排列方式弄抬,可以設(shè)置為horizontal、vertical兩個值之一

其中宪郊,gravity屬性支持top, left, right, center_vertical, fill_vertical, center_horizontal, fill_horizontal, center, fill, clip_vertical, clip_horizontal掂恕。也可以同時指定多種對齊方式的組合。

LinearLayout子元素支持的常用XML屬性及方法

XML屬性說明

android:layout_gravity指定該子元素在LinearLayout中的對齊方式

android:layout_weight指定子元素在LinearLayout中所占的權(quán)重

2. TableLayout表格布局

TableLayout繼承自Linearout弛槐,本質(zhì)上仍然是線性布局管理器懊亡。表格布局采用行、列的形式來管理UI組件乎串,并不需要明確地聲明包含多少行店枣、多少列,而是通過添加TableRow叹誉、其他組件來控制表格的行數(shù)和列數(shù)鸯两。

每向TableLayout中添加一個TableRow就代表一行;

每向TableRow中添加一個一個子組件就表示一列长豁;

如果直接向TableLayout添加組件钧唐,那么該組件將直接占用一行;

在表格布局中匠襟,可以為單元格設(shè)置如下三種行為方式:

Shrinkable:該列的所有單元格的寬度可以被收縮钝侠,以保證該表格能適應(yīng)父容器的寬度;

Strentchable:該列所有單元格的寬度可以被拉伸宅此,以保證組件能完全填滿表格空余空間机错;

Collapsed:如果該列被設(shè)置為Collapsed,那么該列的所有單元格會被隱藏父腕;

TableLayout的常用XML屬性及方法

XML屬性相關(guān)方法說明

android:collapseColumnssetColumns(int, boolean)設(shè)置需要被隱藏的列的序號弱匪,多個序號間用逗號分隔

android:shrinkColumnssetShrinkAllColumns(boolean)設(shè)置需要被收縮的列的序號

android:stretchColumnssetStretchAllColumns(boolean)設(shè)置允許被拉伸的列的序號

3. FrameLayout幀布局

FrameLayout直接繼承自ViewGroup組件。幀布局為每個加入其中的組件創(chuàng)建一個空白的區(qū)域(稱為一幀)璧亮,每個子組件占據(jù)一幀萧诫,這些幀會根據(jù)gravity屬性執(zhí)行自動對齊。

FrameLayout的常用XM了屬性及方法

XML屬性相關(guān)方法說明

android:foregroundsetForeground(Drawable)設(shè)置該幀布局容器的前景圖像

android:foregroundGravitysetForeGroundGraity(int)定義繪制前景圖像的gravity屬性

4. RelativeLayout相對布局

RelativeLayout的XML屬性及相關(guān)方法說明

XML屬性相關(guān)方法說明

android:gravitysetGravity(int)?

android:ignoreGravitysetIgnoreGravity(int)設(shè)置哪個組件不受gravity屬性的影響

為了控制該布局容器的各子組件的布局分布枝嘶,RelativeLayout提供了一個內(nèi)部類:RelativeLayout.LayoutParams帘饶。

RelativeLayout.LayoutParams里只能設(shè)為boolean的XML屬性

XML屬性說明

android:layout_centerHorizontal設(shè)置該子組件是否位于布局容器的水平居中

android:layout_centerVertical?

android:layout_centerParent?

android:layout_alignParentBottom?

android:layout_alignParentLeft?

android:layout_alignParentRight?

android:layout_alignParentTop

RelativeLayout.LayoutParams里屬性值為其他UI組件ID的XML屬性

XML屬性說明

android:layout_toRightOf控制該子組件位于給出ID組件的右側(cè)

android:layout_toLeftOf?

android:layout_above?

android:layout_below?

android:layout_alignTop?

android:layout_alignBottom?

android:layout_alignRight?

android:layout_alignLeft

5. Android 4.0新增的網(wǎng)格布局GridLayout

GridLayout是Android4.0增加的網(wǎng)格布局控件,與之前的TableLayout有些相似群扶,它把整個容器劃分為rows × columns個網(wǎng)格及刻,每個網(wǎng)格可以放置一個組件镀裤。性能及功能都要比tablelayout好,比如GridLayout布局中的單元格可以跨越多行缴饭,而tablelayout則不行暑劝,此外,其渲染速度也比tablelayout要快颗搂。

GridLayout提供了setRowCount(int)和setColumnCount(int)方法來控制該網(wǎng)格的行和列的數(shù)量担猛。

GridLayout常用的XML屬性和方法說明

XML屬性相關(guān)方法說明

android:alignmentModesetAlignmentMode(int)設(shè)置該布局管理器采用的對齊模式

android:columnCountsetColumnCount(int)設(shè)置該網(wǎng)格的列數(shù)量

android:columnOrderPreservedsetColumnOrderPreserved(boolean)設(shè)置該網(wǎng)格容器是否保留序列號

android:roeCountsetRowCount(int)設(shè)置該網(wǎng)格的行數(shù)量

android:rowOrderPreservedsetRowOrderPreserved(boolean)設(shè)置該網(wǎng)格容器是否保留行序號

android:useDefaultMarginssetUseDefaultMargins(boolean)設(shè)置該布局管理器是否使用默認的頁邊距

為了控制GridLayout布局容器中各子組件的布局分布,GridLayout提供了一個內(nèi)部類:GridLayout.LayoutParams丢氢,來控制Gridlayout布局容器中子組件的布局分布傅联。

GridLayout.LayoutParams常用的XML屬性和方法說明

XML屬性說明

android:layout_column設(shè)置該組件在GridLayout的第幾列

android:layout_columnSpan設(shè)置該子組件在GridLayout橫向上跨幾列

android:layout_gravity設(shè)置該子組件采用何種方式占據(jù)該網(wǎng)格的空間

android:layout_row設(shè)置該子組件在GridLayout的第幾行

android:layout_rowSpan設(shè)置該子組件在GridLayout縱向上跨幾行

6. AbsoluteLayout絕對布局

即Android不提供任何布局控制,而是由開發(fā)人員自己通過X坐標(biāo)疚察、Y坐標(biāo)來控制組件的位置蒸走。每個組件都可指定如下兩個XML屬性:

layour_x;

layout_y;

絕對布局已經(jīng)過時,不應(yīng)使用或少使用稍浆。

界面布局類型的選擇和性能優(yōu)化

首先得明確载碌,界面布局類型的嵌套越多越深越復(fù)雜,會使布局實例化變慢衅枫,使Activity的展開時間延長嫁艇。建議盡量減少布局嵌套,盡量減少創(chuàng)建View對象的數(shù)量弦撩。

1 . 減少布局層次步咪,可考慮用RelativeLayout來代替LinearLayout。通過Relative的相對其他元素的位置來布局益楼,可減少塊狀嵌套猾漫;

2 . 另一種減少布局層次的技巧是使用標(biāo)簽來合并布局;

3 . 重用布局感凤。Android支持在XML中使用標(biāo)簽悯周,通過指定android:layout屬性來指定要包含的另一個XML布局。

如:

1

2

3

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?三.五大存儲:

Android中陪竿,可供選擇的存儲方式有SharedPreferences禽翼、文件存儲、SQLite數(shù)據(jù)庫方式族跛、內(nèi)容提供器(Content provider)和網(wǎng)絡(luò)闰挡。

一.SharedPreferences方式

??????? Android提供用來存儲一些簡單的配置信息的一種機制,例如礁哄,一些默認歡迎語长酗、登錄的用戶名和密碼等。其以鍵值對的方式存儲桐绒,

使得我們可以很方便的讀取和存入.

1)程序要實現(xiàn)的功能:

我們在Name文本框中輸入wangwu夺脾,在Password文本框中輸入123456之拨,然后退出這個應(yīng)用。我們在應(yīng)用程序列表中找到這個應(yīng)用咧叭,重新啟動敦锌,可以看到其使用了前面輸入的Name和Password

?????? 2)實現(xiàn)的代碼

?????? 布局


view plaincopy to clipboard


????android:orientation="vertical"??

????android:layout_width="fill_parent"??

????android:layout_height="fill_parent"??

????>??


????????android:layout_width="fill_parent"???

????????android:layout_height="wrap_content"???

????????android:text="SharedPreferences?demo"??

????/>??



????????android:layout_width="fill_parent"??

????????android:layout_height="wrap_content"??

????????android:text="name"??

????????>??




????????android:id="@+id/name"??

????????android:layout_width="fill_parent"??

????????android:layout_height="wrap_content"??

????????android:text=""??

????????>??




????????android:layout_width="fill_parent"??

????????android:layout_height="wrap_content"??

????????android:text="password"??

????????>??




????????android:id="@+id/password"??

????????android:layout_width="fill_parent"??

????????android:layout_height="wrap_content"??

????????android:password="true"??

????????android:text=""??

????????>??




??????? 主要實現(xiàn)代碼


view plaincopy to clipboard

package?com.demo;??


import?android.app.Activity;??

import?android.content.SharedPreferences;??

import?android.os.Bundle;??

import?android.widget.EditText;??


public?class?SharedPreferencesDemo?extends?Activity?{??


????public?static?final?String?SETTING_INFOS?=?"SETTING_Infos";???

????public?static?final?String?NAME?=?"NAME";???

????public?static?final?String?PASSWORD?=?"PASSWORD";???

????private?EditText?field_name;??//接收用戶名的組件???

????private?EditText?filed_pass;??//接收密碼的組件???


????@Override??

????public?void?onCreate(Bundle?savedInstanceState)?{??

????????super.onCreate(savedInstanceState);??

????????setContentView(R.layout.main);??


????????//Find?VIew????

????????field_name?=?(EditText)?findViewById(R.id.name);??//首先獲取用來輸入用戶名的組件???

????????filed_pass?=?(EditText)?findViewById(R.id.password);?//同時也需要獲取輸入密碼的組件???


????????//?Restore?preferences???

????????SharedPreferences?settings?=?getSharedPreferences(SETTING_INFOS,?0);?//獲取一個SharedPreferences對象???

????????String?name?=?settings.getString(NAME,?"");??//取出保存的NAME???

????????String?password?=?settings.getString(PASSWORD,?"");?//取出保存的PASSWORD???


????????//Set?value???

????????field_name.setText(name);??//將取出來的用戶名賦予field_name???

????????filed_pass.setText(password);??//將取出來的密碼賦予filed_pass???

????}??


????@Override???

????protected?void?onStop(){???

????????super.onStop();???


????????SharedPreferences?settings?=?getSharedPreferences(SETTING_INFOS,?0);?//首先獲取一個SharedPreferences對象???

????????settings.edit()???

????????????????.putString(NAME,?field_name.getText().toString())???

????????????????.putString(PASSWORD,?filed_pass.getText().toString())???

????????????????.commit();???

????}?//將用戶名和密碼保存進去???


} ?


?????? SharedPreferences保存到哪里去了?

???????SharedPreferences是以XML的格式以文件的方式自動保存的佳簸,在DDMS中的File Explorer中展開到/data/data/

name>/shared_prefs下,以上面這個為例颖变,可以看到一個叫做SETTING_Infos.xml的文件

注意:Preferences只能在同一個包內(nèi)使用生均,不能在不同的包之間使用。

二.文件存儲方式

在Android中腥刹,其提供了openFileInput 和 openFileOuput 方法讀取設(shè)備上的文件马胧,下面看個例子代碼,具體如下所示:

String FILE_NAME = "tempfile.tmp";? //確定要操作文件的文件名

FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE); //初始化

FileInputStream fis = openFileInput(FILE_NAME); //創(chuàng)建寫入流

?????? 上述代碼中兩個方法只支持讀取該應(yīng)用目錄下的文件衔峰,讀取非其自身目錄下的文件將會拋出異常佩脊。需要提醒的是,如果調(diào)用

FileOutputStream 時指定的文件不存在垫卤,Android 會自動創(chuàng)建它威彰。另外,在默認情況下穴肘,寫入的時候會覆蓋原文件內(nèi)容歇盼,如果想把

新寫入的內(nèi)容附加到原文件內(nèi)容后,則可以指定其模式為Context.MODE_APPEND评抚。


三.SQLite數(shù)據(jù)庫方式

SQLite是Android所帶的一個標(biāo)準(zhǔn)的數(shù)據(jù)庫豹缀,它支持SQL語句,它是一個輕量級的嵌入式數(shù)據(jù)庫慨代。

1)實現(xiàn)的功能

????????? 在這個例子里邊邢笙,我們在程序的主界面有一些按鈕,通過這些按鈕可以對數(shù)據(jù)庫進行標(biāo)準(zhǔn)的增侍匙、刪氮惯、改、查丈积。

??????2)實現(xiàn)代碼

????????? 所用到的字符文件


view plaincopy to clipboard


??

????SQLite數(shù)據(jù)庫操作實例??

????建立數(shù)據(jù)庫表??

????刪除數(shù)據(jù)庫表??

????插入兩條記錄??

????刪除一條記錄??

????查看數(shù)據(jù)庫表??


????????? 布局代碼


view plaincopy to clipboard


????android:orientation="vertical"??

????android:layout_width="fill_parent"??

????android:layout_height="fill_parent"??

????>??



????????android:layout_width="fill_parent"???

????????android:layout_height="wrap_content"???

????????android:text="@string/app_name"??

????/>??


????????android:text="@string/button1"???

????????android:id="@+id/button1"???

????????android:layout_width="wrap_content"???

????????android:layout_height="wrap_content"??

????????>??


????????android:text="@string/button2"???

????????android:id="@+id/button2"???

????????android:layout_width="wrap_content"???

????????android:layout_height="wrap_content"??

????????>??


????????android:text="@string/button3"???

????????android:id="@+id/button3"???

????????android:layout_width="wrap_content"???

????????android:layout_height="wrap_content"??

????????>??


????????android:text="@string/button4"???

????????android:id="@+id/button4"???

????????android:layout_width="wrap_content"???

????????android:layout_height="wrap_content"??

????????>??


????????android:text="@string/button5"???

????????android:id="@+id/button5"???

????????android:layout_width="wrap_content"???

????????android:layout_height="wrap_content"??

????????>??



????????? 主要代碼


view plaincopy to clipboard

package?com.sqlite;??


import?android.app.Activity;??

import?android.content.Context;??

import?android.database.Cursor;??

import?android.database.SQLException;??

import?android.database.sqlite.SQLiteDatabase;??

import?android.database.sqlite.SQLiteOpenHelper;??

import?android.os.Bundle;??

import?android.util.Log;??

import?android.view.View;??

import?android.view.View.OnClickListener;??

import?android.widget.Button;??


/*

?*?什么是SQLiteDatabase筐骇?

?*?一個SQLiteDatabase的實例代表了一個SQLite的數(shù)據(jù)庫,通過SQLiteDatabase實例的一些方法江滨,我們可以執(zhí)行SQL語句铛纬,

?*?對數(shù)據(jù)庫進行增、刪唬滑、查告唆、改的操作棺弊。需要注意的是,數(shù)據(jù)庫對于一個應(yīng)用來說是私有的擒悬,并且在一個應(yīng)用當(dāng)中模她,數(shù)據(jù)庫的名字也是惟一的。?

?*/??


/*

?*?什么是SQLiteOpenHelper?懂牧??

?*?這個類主要生成一個數(shù)據(jù)庫侈净,并對數(shù)據(jù)庫的版本進行管理。

?*?當(dāng)在程序當(dāng)中調(diào)用這個類的方法getWritableDatabase()或者getReadableDatabase()方法的時候僧凤,如果當(dāng)時沒有數(shù)據(jù)畜侦,那么Android系統(tǒng)就會自動生成一個數(shù)據(jù)庫。

?*?SQLiteOpenHelper?是一個抽象類躯保,我們通常需要繼承它旋膳,并且實現(xiàn)里邊的3個函數(shù),

?*?????onCreate(SQLiteDatabase):在數(shù)據(jù)庫第一次生成的時候會調(diào)用這個方法途事,一般我們在這個方法里邊生成數(shù)據(jù)庫表验懊。

?*?????onUpgrade(SQLiteDatabase,?int,?int):當(dāng)數(shù)據(jù)庫需要升級的時候,Android系統(tǒng)會主動的調(diào)用這個方法尸变。一般我們在這個方法里邊刪除數(shù)據(jù)表义图,并建立新的數(shù)據(jù)表,當(dāng)然是否還需要做其他的操作振惰,完全取決于應(yīng)用的需求歌溉。

?*?????onOpen(SQLiteDatabase):這是當(dāng)打開數(shù)據(jù)庫時的回調(diào)函數(shù),一般也不會用到骑晶。?

?*/??


public?class?SQLiteDemo?extends?Activity?{??


????OnClickListener?listener1?=?null;??

????OnClickListener?listener2?=?null;??

????OnClickListener?listener3?=?null;??

????OnClickListener?listener4?=?null;??

????OnClickListener?listener5?=?null;??


????Button?button1;??

????Button?button2;??

????Button?button3;??

????Button?button4;??

????Button?button5;??


????DatabaseHelper?mOpenHelper;??


????private?static?final?String?DATABASE_NAME?=?"dbForTest.db";??

????private?static?final?int?DATABASE_VERSION?=?1;??

????private?static?final?String?TABLE_NAME?=?"diary";??

????private?static?final?String?TITLE?=?"title";??

????private?static?final?String?BODY?=?"body";??


????//建立一個內(nèi)部類,主要生成一個數(shù)據(jù)庫???

????private?static?class?DatabaseHelper?extends?SQLiteOpenHelper?{??


????????DatabaseHelper(Context?context)?{??

????????????super(context,?DATABASE_NAME,?null,?DATABASE_VERSION);??

????????}??


????????//在數(shù)據(jù)庫第一次生成的時候會調(diào)用這個方法痛垛,一般我們在這個方法里邊生成數(shù)據(jù)庫表。???

????????@Override??

????????public?void?onCreate(SQLiteDatabase?db)?{??


????????????String?sql?=?"CREATE?TABLE?"?+?TABLE_NAME?+?"?("?+?TITLE??

????????????????????+?"?text?not?null,?"?+?BODY?+?"?text?not?null?"?+?");";??

????????????Log.i("haiyang:createDB=",?sql);??

????????????db.execSQL(sql);??

????????}??


????????@Override??

????????public?void?onUpgrade(SQLiteDatabase?db,?int?oldVersion,?int?newVersion)?{??

????????}??

????}??


????@Override??

????public?void?onCreate(Bundle?savedInstanceState)?{??

????????super.onCreate(savedInstanceState);??

????????setContentView(R.layout.main);??

????????prepareListener();??

????????initLayout();??

????????mOpenHelper?=?new?DatabaseHelper(this);??


????}??


????private?void?initLayout()?{??

????????button1?=?(Button)?findViewById(R.id.button1);??

????????button1.setOnClickListener(listener1);??


????????button2?=?(Button)?findViewById(R.id.button2);??

????????button2.setOnClickListener(listener2);??


????????button3?=?(Button)?findViewById(R.id.button3);??

????????button3.setOnClickListener(listener3);??


????????button4?=?(Button)?findViewById(R.id.button4);??

????????button4.setOnClickListener(listener4);??


????????button5?=?(Button)?findViewById(R.id.button5);??

????????button5.setOnClickListener(listener5);??


????}??


????private?void?prepareListener()?{??

????????listener1?=?new?OnClickListener()?{??

????????????public?void?onClick(View?v)?{??

????????????????CreateTable();??

????????????}??

????????};??

????????listener2?=?new?OnClickListener()?{??

????????????public?void?onClick(View?v)?{??

????????????????dropTable();??

????????????}??

????????};??

????????listener3?=?new?OnClickListener()?{??

????????????public?void?onClick(View?v)?{??

????????????????insertItem();??

????????????}??

????????};??

????????listener4?=?new?OnClickListener()?{??

????????????public?void?onClick(View?v)?{??

????????????????deleteItem();??

????????????}??

????????};??

????????listener5?=?new?OnClickListener()?{??

????????????public?void?onClick(View?v)?{??

????????????????showItems();??

????????????}??

????????};??

????}??


????/*

?????*?重新建立數(shù)據(jù)表

?????*/??

????private?void?CreateTable()?{??

????????//mOpenHelper.getWritableDatabase()語句負責(zé)得到一個可寫的SQLite數(shù)據(jù)庫桶蛔,如果這個數(shù)據(jù)庫還沒有建立匙头,???

????????//那么mOpenHelper輔助類負責(zé)建立這個數(shù)據(jù)庫。如果數(shù)據(jù)庫已經(jīng)建立仔雷,那么直接返回一個可寫的數(shù)據(jù)庫蹂析。???

????????SQLiteDatabase?db?=?mOpenHelper.getWritableDatabase();??

????????String?sql?=?"CREATE?TABLE?"?+?TABLE_NAME?+?"?("?+?TITLE??

????????????????+?"?text?not?null,?"?+?BODY?+?"?text?not?null?"?+?");";??

????????Log.i("haiyang:createDB=",?sql);??


????????try?{??

????????????db.execSQL("DROP?TABLE?IF?EXISTS?diary");??

????????????db.execSQL(sql);??

????????????setTitle("數(shù)據(jù)表成功重建");??

????????}?catch?(SQLException?e)?{??

????????????setTitle("數(shù)據(jù)表重建錯誤");??

????????}??

????}??


????/*

?????*?刪除數(shù)據(jù)表

?????*/??

????private?void?dropTable()?{??

????????//mOpenHelper.getWritableDatabase()語句負責(zé)得到一個可寫的SQLite數(shù)據(jù)庫,如果這個數(shù)據(jù)庫還沒有建立碟婆,???

????????//那么mOpenHelper輔助類負責(zé)建立這個數(shù)據(jù)庫电抚。如果數(shù)據(jù)庫已經(jīng)建立,那么直接返回一個可寫的數(shù)據(jù)庫竖共。???

????????SQLiteDatabase?db?=?mOpenHelper.getWritableDatabase();??

????????String?sql?=?"drop?table?"?+?TABLE_NAME;??

????????try?{??

????????????db.execSQL(sql);??

????????????setTitle("數(shù)據(jù)表成功刪除:"?+?sql);??

????????}?catch?(SQLException?e)?{??

????????????setTitle("數(shù)據(jù)表刪除錯誤");??

????????}??

????}??


????/*

?????*?插入兩條數(shù)據(jù)

?????*/??

????private?void?insertItem()?{??

????????//mOpenHelper.getWritableDatabase()語句負責(zé)得到一個可寫的SQLite數(shù)據(jù)庫蝙叛,如果這個數(shù)據(jù)庫還沒有建立,???

????????//那么mOpenHelper輔助類負責(zé)建立這個數(shù)據(jù)庫公给。如果數(shù)據(jù)庫已經(jīng)建立借帘,那么直接返回一個可寫的數(shù)據(jù)庫蜘渣。???

????????SQLiteDatabase?db?=?mOpenHelper.getWritableDatabase();??

????????String?sql1?=?"insert?into?"?+?TABLE_NAME?+?"?("?+?TITLE?+?",?"?+?BODY??

????????????????+?")?values('haiyang',?'android的發(fā)展真是迅速啊');";??

????????String?sql2?=?"insert?into?"?+?TABLE_NAME?+?"?("?+?TITLE?+?",?"?+?BODY??

????????????????+?")?values('icesky',?'android的發(fā)展真是迅速啊');";??

????????try?{??

????????????//?Log.i()會將參數(shù)內(nèi)容打印到日志當(dāng)中,并且打印級別是Info級別???

????????????//?Android支持5種打印級別肺然,分別是Verbose蔫缸、Debug、Info际起、Warning拾碌、Error,當(dāng)然我們在程序當(dāng)中一般用到的是Info級別???

????????????Log.i("haiyang:sql1=",?sql1);??

????????????Log.i("haiyang:sql2=",?sql2);??

????????????db.execSQL(sql1);??

????????????db.execSQL(sql2);??

????????????setTitle("插入兩條數(shù)據(jù)成功");??

????????}?catch?(SQLException?e)?{??

????????????setTitle("插入兩條數(shù)據(jù)失敗");??

????????}??

????}??


????/*

?????*?刪除其中的一條數(shù)據(jù)

?????*/??

????private?void?deleteItem()?{??

????????try?{??

????????????//mOpenHelper.getWritableDatabase()語句負責(zé)得到一個可寫的SQLite數(shù)據(jù)庫街望,如果這個數(shù)據(jù)庫還沒有建立倦沧,???

????????????//那么mOpenHelper輔助類負責(zé)建立這個數(shù)據(jù)庫。如果數(shù)據(jù)庫已經(jīng)建立它匕,那么直接返回一個可寫的數(shù)據(jù)庫。???

????????????SQLiteDatabase?db?=?mOpenHelper.getWritableDatabase();??

????????????//第一個參數(shù)是數(shù)據(jù)庫表名窖认,在這里是TABLE_NAME豫柬,也就是diary。????

????????????//第二個參數(shù)扑浸,相當(dāng)于SQL語句當(dāng)中的where部分烧给,也就是描述了刪除的條件。???

????????????//如果在第二個參數(shù)當(dāng)中有“喝噪?”符號础嫡,那么第三個參數(shù)中的字符串會依次替換在第二個參數(shù)當(dāng)中出現(xiàn)的“?”符號酝惧。????

????????????db.delete(TABLE_NAME,?"?title?=?'haiyang'",?null);??

????????????setTitle("刪除title為haiyang的一條記錄");??

????????}?catch?(SQLException?e)?{??


????????}??


????}??


????/*

?????*?在屏幕的title區(qū)域顯示當(dāng)前數(shù)據(jù)表當(dāng)中的數(shù)據(jù)的條數(shù)榴鼎。

?????*/??

????/*

?????*?Cursor?cur?=?db.query(TABLE_NAME,?col,?null,?null,?null,?null,?null)語句將查詢到的數(shù)據(jù)放到一個Cursor?當(dāng)中。

????????這個Cursor里邊封裝了這個數(shù)據(jù)表TABLE_NAME當(dāng)中的所有條列晚唇。?

????????query()方法相當(dāng)?shù)挠杏梦撞疲谶@里我們簡單地講一下。

????????????第一個參數(shù)是數(shù)據(jù)庫里邊表的名字哩陕,比如在我們這個例子平项,表的名字就是TABLE_NAME,也就是"diary"悍及。

????????????第二個字段是我們想要返回數(shù)據(jù)包含的列的信息闽瓢。在這個例子當(dāng)中我們想要得到的列有title、body心赶。我們把這兩個列的名字放到字符串?dāng)?shù)組里邊來扣讼。

????????????第三個參數(shù)為selection,相當(dāng)于SQL語句的where部分园担,如果想返回所有的數(shù)據(jù)届谈,那么就直接置為null枯夜。

????????????第四個參數(shù)為selectionArgs。在selection部分艰山,你有可能用到“?”湖雹,那么在selectionArgs定義的字符串會代替selection中的“?”。

????????????第五個參數(shù)為groupBy曙搬。定義查詢出來的數(shù)據(jù)是否分組摔吏,如果為null則說明不用分組。

????????????第六個參數(shù)為having?纵装,相當(dāng)于SQL語句當(dāng)中的having部分征讲。

????????????第七個參數(shù)為orderBy,來描述我們期望的返回值是否需要排序橡娄,如果設(shè)置為null則說明不需要排序诗箍。

?????*/??


????private?void?showItems()?{??


????????SQLiteDatabase?db?=?mOpenHelper.getReadableDatabase();??

????????String?col[]?=?{?TITLE,?BODY?};??

????????//查詢數(shù)據(jù)???

????????Cursor?cur?=?db.query(TABLE_NAME,?col,?null,?null,?null,?null,?null);??

????????Integer?num?=?cur.getCount();??

????????setTitle(Integer.toString(num)?+?"?條記錄");??

????}??

} ?cop?

四.內(nèi)容提供器(Content provider)方式

????? 在Android的設(shè)計“哲學(xué)”里是鼓勵開發(fā)者使用內(nèi)部類的,這樣不但使用方便挽唉,而且執(zhí)行效率也高滤祖。

1.什么是ContentProvider

數(shù)據(jù)在Android當(dāng)中是私有的,當(dāng)然這些數(shù)據(jù)包括文件數(shù)據(jù)和數(shù)據(jù)庫數(shù)據(jù)以及一些其他類型的數(shù)據(jù)瓶籽。難道兩個程序之間就沒有辦法對于數(shù)據(jù)進行交換匠童?解決這個問題主要靠ContentProvider。

一個Content Provider類實現(xiàn)了一組標(biāo)準(zhǔn)的方法接口塑顺,從而能夠讓其他的應(yīng)用保存或讀取此Content Provider的各種數(shù)據(jù)類型汤求。也就是說,一個程序可以通過實現(xiàn)一個Content Provider的抽象接口將自己的數(shù)據(jù)暴露出去严拒。外界根本看不到扬绪,也不用看到這個應(yīng)用暴露的數(shù)據(jù)在應(yīng)用當(dāng)中是如何存儲的,或者是用數(shù)據(jù)庫存儲還是用文件存儲裤唠,還是通過網(wǎng)上獲得勒奇,這些一切都不重要,重要的是外界可以通過這一套標(biāo)準(zhǔn)及統(tǒng)一的接口和程序里的數(shù)據(jù)打交道巧骚,可以讀取程序的數(shù)據(jù)赊颠,也可以刪除程序的數(shù)據(jù),當(dāng)然劈彪,中間也會涉及一些權(quán)限的問題竣蹦。

下邊列舉一些較常見的接口,這些接口如下所示沧奴。

query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder):通過Uri進行查詢痘括,返回一個Cursor。

insert(Uri url, ContentValues values):將一組數(shù)據(jù)插入到Uri 指定的地方。

update(Uri uri, ContentValues values, String where, String[] selectionArgs):更新Uri指定位置的數(shù)據(jù)纲菌。

delete(Uri url, String where, String[] selectionArgs):刪除指定Uri并且符合一定條件的數(shù)據(jù)挠日。

2.什么是ContentResolver

外界的程序通過ContentResolver接口可以訪問ContentProvider提供的數(shù)據(jù),在Activity當(dāng)中通過getContentResolver()可以得到當(dāng)前應(yīng)用的ContentResolver實例翰舌。

ContentResolver提供的接口和ContentProvider中需要實現(xiàn)的接口對應(yīng)嚣潜,主要有以下幾個刁岸。

query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder):通過Uri進行查詢缚陷,返回一個Cursor霞篡。

insert(Uri url, ContentValues values):將一組數(shù)據(jù)插入到Uri 指定的地方鹿鳖。

update(Uri uri, ContentValues values, String where, String[] selectionArgs):更新Uri指定位置的數(shù)據(jù)。

delete(Uri url, String where, String[] selectionArgs):刪除指定Uri并且符合一定條件的數(shù)據(jù)吻谋。

????? 3.ContentProvider和ContentResolver中用到的Uri

在ContentProvider和ContentResolver當(dāng)中用到了Uri的形式通常有兩種妻导,一種是指定全部數(shù)據(jù)嗤瞎,另一種是指定某個ID的數(shù)據(jù)山橄。

我們看下面的例子垮媒。

content://contacts/people/? 這個Uri指定的就是全部的聯(lián)系人數(shù)據(jù)。

content://contacts/people/1 這個Uri指定的是ID為1的聯(lián)系人的數(shù)據(jù)航棱。

在上邊兩個類中用到的Uri一般由3部分組成涣澡。

第一部分是:"content://" 。

第二部分是要獲得數(shù)據(jù)的一個字符串片段丧诺。

最后就是ID(如果沒有指定ID,那么表示返回全部)奄薇。

由于URI通常比較長驳阎,而且有時候容易出錯,且難以理解馁蒂。所以呵晚,在Android當(dāng)中定義了一些輔助類,并且定義了一些常量來代替這些長字符串的使用沫屡,例如下邊的代碼:

Contacts.People.CONTENT_URI (聯(lián)系人的URI)饵隙。

1)實現(xiàn)的功能

???????? 在這個例子里邊,首先在系統(tǒng)的聯(lián)系人應(yīng)用當(dāng)中插入一些聯(lián)系人信息沮脖,然后把這些聯(lián)系人的名字和電話再顯示出來

???? 2)實現(xiàn)方法


view plaincopy to clipboard

package?com.contentProvider;??


import?android.app.ListActivity;??

import?android.database.Cursor;??

import?android.os.Bundle;??

import?android.provider.Contacts.Phones;??

import?android.widget.ListAdapter;??

import?android.widget.SimpleCursorAdapter;??


public?class?ContentProviderDemo?extends?ListActivity?{??


????protected?void?onCreate(Bundle?savedInstanceState)?{??

????????super.onCreate(savedInstanceState);??

????????//getContentResolver()方法得到應(yīng)用的ContentResolver實例金矛。???

????????//?query(Phones.CONTENT_URI,?null,?null,?null,?null)。它是ContentResolver里的方法勺届,負責(zé)查詢所有聯(lián)系人驶俊,并返回一個Cursor。這個方法參數(shù)比較多免姿,每個參數(shù)的具體含義如下饼酿。???

????????//·??第一個參數(shù)為Uri,在這個例子里邊這個Uri是聯(lián)系人的Uri。???

????????//·??第二個參數(shù)是一個字符串的數(shù)組故俐,數(shù)組里邊的每一個字符串都是數(shù)據(jù)表中某一列的名字想鹰,它指定返回數(shù)據(jù)表中那些列的值。???

????????//·??第三個參數(shù)相當(dāng)于SQL語句的where部分药版,描述哪些值是我們需要的辑舷。???

????????//·??第四個參數(shù)是一個字符串?dāng)?shù)組,它里邊的值依次代替在第三個參數(shù)中出現(xiàn)的“?”符號刚陡。???

????????//·??第五個參數(shù)指定了排序的方式惩妇。???

????????Cursor?c?=?getContentResolver().query(Phones.CONTENT_URI,?null,?null,?null,?null);??

????????startManagingCursor(c);?//讓系統(tǒng)來管理生成的Cursor。???

????????ListAdapter?adapter?=?new?SimpleCursorAdapter(??

????????????????this,??

????????????????android.R.layout.simple_list_item_2,???

????????????????c,???

????????????????new?String[]?{?Phones.NAME,?Phones.NUMBER?},???

????????????????new?int[]?{?android.R.id.text1,?android.R.id.text2?});??

????????setListAdapter(adapter);?//將ListView和SimpleCursorAdapter進行綁定筐乳。???

????}??


} ?

五. 網(wǎng)絡(luò)存儲方式


?1.例子介紹

通過郵政編碼查詢該地區(qū)的天氣預(yù)報歌殃,以POST發(fā)送的方式發(fā)送請求到webservicex.net站點,訪問WebService.webservicex.net站點上提供查詢天氣預(yù)報的服務(wù)蝙云,具體信息請參考其WSDL文檔氓皱,網(wǎng)址為:

http://www.webservicex.net/WeatherForecast.asmx?WSDL

輸入:美國某個城市的郵政編碼勃刨。

輸出:該郵政編碼對應(yīng)城市的天氣預(yù)報波材。

2.實現(xiàn)步驟如下

(1)如果需要訪問外部網(wǎng)絡(luò),則需要在AndroidManifest.xml文件中加入如下代碼申請權(quán)限許可:


(2)以HTTP POST的方式發(fā)送(注意:SERVER_URL并不是指WSDL的URL身隐,而是服務(wù)本身的URL)廷区。實現(xiàn)的代碼如下所示:

private static final String SERVER_URL = "

http://www.webservicex.net/WeatherForecast. asmx/GetWeatherByZipCode"; //定義需要獲取的內(nèi)容來源地址

HttpPost request = new HttpPost(SERVER_URL); //根據(jù)內(nèi)容來源地址創(chuàng)建一個Http請求

// 添加一個變量

List params = new ArrayList ();

// 設(shè)置一個華盛頓區(qū)號

params.add(new BasicNameValuePair("ZipCode", "200120"));? //添加必須的參數(shù)

request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); //設(shè)置參數(shù)的編碼

try {

HttpResponse httpResponse = new DefaultHttpClient().execute(request); //發(fā)送請求并獲取反饋

// 解析返回的內(nèi)容

if(httpResponse.getStatusLine().getStatusCode() != 404)

{

String result = EntityUtils.toString(httpResponse.getEntity());

Log.d(LOG_TAG, result);

}

} catch (Exception e) {

Log.e(LOG_TAG, e.getMessage());

}

代碼解釋:

如上代碼使用Http從webservicex獲取ZipCode為“200120”(美國WASHINGTON D.C)的內(nèi)容,其返回的內(nèi)容如下:

http://www.w3.org/2001/XMLSchema" xmlns:xsi="http: //www.w3.org/2001/XMLSchema-instance" xmlns="http://www.webservicex.net">

38.97571

77.02825

0.024849

11

WASHINGTON

DC

Saturday, April 25, 2009

http://forecast.weather.gov/images/wtf/sct.jpg

88

57

31

14

Sunday, April 26, 2009

http://forecast.weather.gov/images/wtf/few.jpg

89

60

32

16

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贾铝,一起剝皮案震驚了整個濱河市隙轻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌垢揩,老刑警劉巖玖绿,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異叁巨,居然都是意外死亡斑匪,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門锋勺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蚀瘸,“玉大人,你說我怎么就攤上這事庶橱〔越” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵悬包,是天一觀的道長衙猪。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么垫释? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任丝格,我火速辦了婚禮,結(jié)果婚禮上棵譬,老公的妹妹穿的比我還像新娘显蝌。我一直安慰自己,他們只是感情好订咸,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布曼尊。 她就那樣靜靜地躺著,像睡著了一般脏嚷。 火紅的嫁衣襯著肌膚如雪骆撇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天父叙,我揣著相機與錄音神郊,去河邊找鬼。 笑死趾唱,一個胖子當(dāng)著我的面吹牛涌乳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播甜癞,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼夕晓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了悠咱?” 一聲冷哼從身側(cè)響起蒸辆,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乔煞,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柒室,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡渡贾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了雄右。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片空骚。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖擂仍,靈堂內(nèi)的尸體忽然破棺而出囤屹,到底是詐尸還是另有隱情,我是刑警寧澤逢渔,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布肋坚,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏智厌。R本人自食惡果不足惜诲泌,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望铣鹏。 院中可真熱鬧敷扫,春花似錦、人聲如沸诚卸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽合溺。三九已至卒密,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間辫愉,已是汗流浹背栅受。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留恭朗,地道東北人屏镊。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像痰腮,于是被迫代替她去往敵國和親而芥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

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