Android-Activity所應(yīng)該了解的大概就這樣。(下)

本文出自 “阿敏其人” 簡書博客漱牵,轉(zhuǎn)載或引用請注明出處。

Android-Activity所應(yīng)該了解的大概就這樣疚漆。(上)

Android-Activity所應(yīng)該了解的大概就這樣酣胀。(中)

六、FLAG

我們知道愿卸,Android給Activity設(shè)定啟動模式的方式有有兩種灵临。一種是在?manifest里面設(shè)置,另一種是在通過Intent的FLAG設(shè)置趴荸。
FLAG儒溉,在安卓里面是 標(biāo)記位 的意思,F(xiàn)lag有很多種发钝,下面我們記錄主要使用的幾種顿涣。

代碼指定Flag(?使用全部FLAG),使得Activity啟動模式可變酝豪,而且最后一次指定的Flag就是該Activity在任務(wù)棧中最終啟動模式涛碑。

  • Intent.FLAG_ACTIVITY_NEW_TASK
    ??注:Intent.FLAG_ACTIVITY_NEW_TASK單獨(dú)使用并無任何效果,需要和taskAffinity一起配合著使用孵淘。

    • 當(dāng)和taskAffinity一起配合著使用時(shí):**Intent.FLAG_ACTIVITY_NEW_TASK + android:taskAffinity 指定非程序包名的任務(wù)棧名蒲障,?與清單文件里面指定 android:launchMode="singleInstance"效果一致 真心一致 ** (情況2示例)
    • 這個(gè)Flag常用于在服務(wù)中啟動Activity,因?yàn)榉?wù)沒有Activity的任務(wù)棧,所以只能用一個(gè)新的任務(wù)棧來啟動這個(gè)Activity創(chuàng)建實(shí)例揉阎。
  • Intent.FLAG_ACTIVITY_SINGLE_TOP
    ??與清單文件里面指定 android:launchMode="singleTop"效果一致庄撮。真心一致。
    ??可嘗試作用采用FLAG_ACTIVITY_CLEAR_TOP退出整個(gè)程序(多activity)

  • Intent.FLAG_ACTIVITY_CLEAR_TOP
    Intent.FLAG_ACTIVITY_CLEAR_TOP與清單文件里面指定 android:launchMode="singleTask"效果類似毙籽,只是類似洞斯。因?yàn)楫?dāng)位于任務(wù)棧頂部的時(shí)候和android:launchMode="singleTask"產(chǎn)生很大的差別
    設(shè)置次標(biāo)記位的Activity,當(dāng)它啟動的時(shí)候坑赡,同一個(gè)任務(wù)棧里面位于他上方的Activity會全部出棧烙如,上方全部清掉。
    在一個(gè)打開時(shí)已經(jīng)被標(biāo)記為FLAG_ACTIVITY_CLEAR_TOP的界面(現(xiàn)正處于前臺任務(wù)棧的棧頂)毅否,如果我們在此界面打開自己亚铁,并且一樣標(biāo)記為FLAG_ACTIVITY_CLEAR_TOP,那么這個(gè)時(shí)候會經(jīng)歷一次建新毀舊的過程螟加,任務(wù)棧里面從結(jié)果的來說沒什么變化刀闷,但是生命周期的著眼于過程的角度來卻經(jīng)歷非常大的變化。(下面的情況5有示例)

mark下仰迁,這個(gè)標(biāo)記位通常是和FLAG_ACTIVITY_NEW_TASK配合著使用的。在這種情況下被啟動的Activty如果已經(jīng)存在顽分,那么系統(tǒng)就會調(diào)用它的onNewIntent方法徐许。如果被調(diào)用的Activity使用默認(rèn)的standrad模式,那么它連同它之上的Activity都要出棧卒蘸,系統(tǒng)會創(chuàng)建新的實(shí)例并入棧置為棧頂雌隅。還未嘗試

  • Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

具有這個(gè)標(biāo)記的Activity不會出現(xiàn)在Activity的歷史列表中.
他等同于在xml里面設(shè)定 android:excludeFromRecents="true" 。

情景實(shí)測:

準(zhǔn)備工作

我們弄一個(gè)程序缸沃,一共有4個(gè)界面恰起,分別是
FirstActivity,這個(gè)作為啟動頁趾牧,接下的描述我們用A代替
SecondActivity 頁面2检盼,接下的描述我們用B代替
ThirdActivity 頁面3 ,接下的描述我們用C代替
FourthActivity 頁面4翘单, 接下的描述我們用D代替

界面布局類似吨枉,每一個(gè)頁面都有TextView寫清楚當(dāng)前是哪一個(gè)界面,并且每一個(gè)界面都會有三個(gè)Button哄芜,都是可以用于啟動頁面2貌亭,頁面3和頁面4.

1.png
2.png
3.png
4.png

就是上面那個(gè)樣子。

準(zhǔn)備工作至此完成

情景1:我們把所有按鈕的打開的Activity都設(shè)置為Intent.FLAG_ACTIVITY_NEW_TASK认臊,只有默認(rèn)的啟動頁是Standard圃庭。

完整過程是:然后啟動app,打開B,在B打開C剧腻,在C打開D拘央,然后在D打開B。
這個(gè)過程我們分兩步進(jìn)行恕酸。

結(jié)論先上:單獨(dú)給Activity的Intent設(shè)置Intent.FLAG_ACTIVITY_NEW_TASK沒有作用堪滨。

如果說Intent.FLAG_ACTIVITY_NEW_TASK直接等同于在xml將來啟動模式設(shè)置為singleTask的話,那么在我們 “在D打開B” 個(gè)操作中蕊温,應(yīng)該此時(shí)任務(wù)棧就應(yīng)該會清掉B以上的C和D袱箱,然后只剩下BA,但是結(jié)果是任務(wù)棧變成了BDCBA义矛,B只是相當(dāng)于一個(gè)普通的實(shí)例入棧发笔。所以這個(gè)說法不成立。

注:網(wǎng)上有人直接說Intent.FLAG_ACTIVITY_NEW_TASK就相當(dāng)于singleTask凉翻,這是錯(cuò)誤的了讨。

貼一下代碼,其實(shí)要是這么設(shè)置Flag特別傻逼制轰,不用這么每個(gè)都設(shè)置的前计,這里為了演示需要,大概怎么設(shè)置后面會提到的

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.amqr.flagtest" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".FirstActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".SecondActivity"/>
        <activity android:name=".ThirdActivity"/>
        <activity android:name=".FourthActivity"/>
    </application>

</manifest>


接下來是四份代碼:
FirstActivity

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);

        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(FirstActivity.this, SecondActivity.class);

                openSecond.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(FirstActivity.this, ThirdActivity.class);

                openThird.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(FirstActivity.this, FourthActivity.class);

                openFourth.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(openFourth);
            }
        });

    }
}

.
.
SecondActivity

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(SecondActivity.this, SecondActivity.class);
                openSecond.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(SecondActivity.this,ThirdActivity.class);
                openThird.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(SecondActivity.this,FourthActivity.class);

                openFourth.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(openFourth);
            }
        });
    }
}


.
.
FourthActivity

public class FourthActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fourth);

        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(FourthActivity.this, SecondActivity.class);

                openSecond.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(FourthActivity.this, ThirdActivity.class);
                openThird.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(FourthActivity.this, FourthActivity.class);
                openFourth.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                startActivity(openFourth);
            }
        });

    }
}

分兩個(gè)步驟垃杖,

第一步:
啟動app后A就啟動男杈,A打開B,B打開C调俘,C打開D
這是我們來看一下終端的信息:

    Running activities (most recent first):
      TaskRecord{52a650dc #6 A=com.amqr.flagtest U=0 sz=4}
        Run #3: ActivityRecord{529b46e4 u0 com.amqr.flagtest/.FourthActivity t6}
        Run #2: ActivityRecord{52983354 u0 com.amqr.flagtest/.ThirdActivity t6}
        Run #1: ActivityRecord{5295f8c8 u0 com.amqr.flagtest/.SecondActivity t6}
        Run #0: ActivityRecord{52958028 u0 com.amqr.flagtest/.FirstActivity t6}


這是任務(wù)棧里面有4個(gè)Activity伶棒,然后里面分別是DCBA,D為棧頂彩库。

第二步:
我們在D界面打開B

然后重新看一下終端的信息:

    Running activities (most recent first):
      TaskRecord{52a650dc #6 A=com.amqr.flagtest U=0 sz=5}
        Run #4: ActivityRecord{52a3efe8 u0 com.amqr.flagtest/.SecondActivity t6}
        Run #3: ActivityRecord{529b46e4 u0 com.amqr.flagtest/.FourthActivity t6}
        Run #2: ActivityRecord{52983354 u0 com.amqr.flagtest/.ThirdActivity t6}
        Run #1: ActivityRecord{5295f8c8 u0 com.amqr.flagtest/.SecondActivity t6}
        Run #0: ActivityRecord{52958028 u0 com.amqr.flagtest/.FirstActivity t6}

情況1再驗(yàn)證.gif

我們發(fā)現(xiàn)肤无,這是在D界面打開的這個(gè)B并沒有把復(fù)用位于A上方的B并且把自己上方的CD清掉,而是像一個(gè)普通的任務(wù)棧入棧了骇钦。
現(xiàn)在任務(wù)棧里面有五個(gè)Activity宛渐,分別是BDCBA,棧頂是第二次打開的B眯搭。

證明結(jié)論:單獨(dú)給Activity的Intent設(shè)置Intent.FLAG_ACTIVITY_NEW_TASK沒有作用皇忿。

.
.

情景2

我們給A打開的B設(shè)置為Intent.FLAG_ACTIVITY_NEW_TASK,給B打開的C設(shè)置為Intent.FLAG_ACTIVITY_NEW_TASK坦仍,給C里面要打開的B和C設(shè)定為Intent.FLAG_ACTIVITY_NEW_TASK鳍烁。
然后重點(diǎn)在這里,在清單文件里面給B和C都屬性taskAffinity屬性繁扎。
我們給B設(shè)置了 android:taskAffinity="com.amqr.second222"
給C設(shè)置了 android:taskAffinity="com.amqr.third333"

結(jié)論先上:**Intent.FLAG_ACTIVITY_NEW_TASK + android:taskAffinity 指定非程序包名的任務(wù)棧名幔荒,?與清單文件里面指定 android:launchMode="singleInstance"效果一致 **
完整操作:A打開B糊闽,B打開C,C再打開C(這里是打不開的)爹梁,C打開B

附上代碼:

manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.amqr.flagtest" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".FirstActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".SecondActivity"
            android:taskAffinity="com.amqr.second222"
            />
        <activity android:name=".ThirdActivity"
            android:taskAffinity="com.amqr.third333"
            />
        <activity android:name=".FourthActivity"/>
    </application>

</manifest>

接下來是代碼
FirstActivity

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);

        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(FirstActivity.this, SecondActivity.class);

                openSecond.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(FirstActivity.this, ThirdActivity.class);


                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(FirstActivity.this, FourthActivity.class);


                startActivity(openFourth);
            }
        });

    }
}

.
.

SecondActivity

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);


        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(SecondActivity.this, SecondActivity.class);

                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(SecondActivity.this, ThirdActivity.class);

                openThird.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(SecondActivity.this, FourthActivity.class);

                startActivity(openFourth);
            }
        });
    }
}

.
.
ThirdActivity

public class ThirdActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);

        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(ThirdActivity.this, SecondActivity.class);

                openSecond.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(ThirdActivity.this, ThirdActivity.class);

                openThird.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(ThirdActivity.this, FourthActivity.class);


                startActivity(openFourth);
            }
        });
    }
}

操作分4步:

提醒:這里B和C被打開時(shí)都被指定 Intent.FLAG_ACTIVITY_NEW_TASK右犹,而且各自都指定了 android:taskAffinity 名稱為非程序包名的自定義任務(wù)棧名稱

步驟1:A打開B,

    Running activities (most recent first):
      TaskRecord{52a6e690 #54 A=com.amqr.second222 U=0 sz=1}
        Run #1: ActivityRecord{529b601c u0 com.amqr.flagtest/.SecondActivity t54}
      TaskRecord{52928e18 #53 A=com.amqr.flagtest U=0 sz=1}
        Run #0: ActivityRecord{5297ded0 u0 com.amqr.flagtest/.FirstActivity t53}

我們發(fā)現(xiàn)此時(shí)程序里面有2個(gè)任務(wù)棧姚垃,一個(gè)是程序自帶的名字為包名的任務(wù)棧amqr.flagtest念链,一個(gè)是我們自定義名字的任務(wù)棧com.amqr.second222。

步驟2:B打開C

    Running activities (most recent first):
      TaskRecord{52b6a93c #55 A=com.amqr.third333 U=0 sz=1}
        Run #2: ActivityRecord{52a8d5f8 u0 com.amqr.flagtest/.ThirdActivity t55}
      TaskRecord{52a6e690 #54 A=com.amqr.second222 U=0 sz=1}
        Run #1: ActivityRecord{529b601c u0 com.amqr.flagtest/.SecondActivity t54}
      TaskRecord{52928e18 #53 A=com.amqr.flagtest U=0 sz=1}
        Run #0: ActivityRecord{5297ded0 u0 com.amqr.flagtest/.FirstActivity t53}

此時(shí)有三個(gè)任務(wù)棧积糯,其中自定義名字的任務(wù)棧com.amqr.third333是前臺任務(wù)棧掂墓,其他兩個(gè)都是后臺任務(wù)棧。

步驟3:C打開C
我們發(fā)現(xiàn)看成,C沒有辦法打開C君编。所以任務(wù)棧里面沒有什么變化

      TaskRecord{52b6a93c #55 A=com.amqr.third333 U=0 sz=1}
        Run #2: ActivityRecord{52a8d5f8 u0 com.amqr.flagtest/.ThirdActivity t55}
      TaskRecord{52a6e690 #54 A=com.amqr.second222 U=0 sz=1}
        Run #1: ActivityRecord{529b601c u0 com.amqr.flagtest/.SecondActivity t54}
      TaskRecord{52928e18 #53 A=com.amqr.flagtest U=0 sz=1}
        Run #0: ActivityRecord{5297ded0 u0 com.amqr.flagtest/.FirstActivity t53}

也就是說,在步驟二的時(shí)候我們的頁面3川慌,也就是ThirdActivity在這個(gè)地方已經(jīng)是存放com.amqr.third333任務(wù)棧里面吃嘿,而且com.amqr.third333是前臺任務(wù)棧,在這種情況下我們進(jìn)行步驟三梦重,在頁面3再打開一次頁面3兑燥,這是沒有任何作用的。復(fù)用頂部琴拧,沒有新的實(shí)例產(chǎn)生贪嫂,需要注意的是,這種方式產(chǎn)生的任務(wù)棧只能存放一個(gè)Activity艾蓝。

步驟4:C打開B

    Running activities (most recent first):
      TaskRecord{52a6e690 #54 A=com.amqr.second222 U=0 sz=1}
        Run #2: ActivityRecord{529b601c u0 com.amqr.flagtest/.SecondActivity t54}
      TaskRecord{52b6a93c #55 A=com.amqr.third333 U=0 sz=1}
        Run #1: ActivityRecord{52a8d5f8 u0 com.amqr.flagtest/.ThirdActivity t55}
      TaskRecord{52928e18 #53 A=com.amqr.flagtest U=0 sz=1}
        Run #0: ActivityRecord{5297ded0 u0 com.amqr.flagtest/.FirstActivity t53}


發(fā)現(xiàn)沒有產(chǎn)生新的任務(wù)棧,也有添加任務(wù)Activity斗塘。但是前臺任務(wù)棧改變了赢织,幾個(gè)任務(wù)棧的順序和前后臺關(guān)系產(chǎn)生了變化,com.amqr.second222由后臺任務(wù)棧變成了前臺任務(wù)棧馍盟。

每一個(gè)任務(wù)棧里面一個(gè)Activity于置,不增不減。

結(jié)論:Intent.FLAG_ACTIVITY_NEW_TASK + android:taskAffinity 指定非程序包名的任務(wù)棧名贞岭,?與清單文件里面指定 android:launchMode="singleInstance"效果一致

.
.

情景3:把所有的按鈕點(diǎn)擊事件的Intent的全部設(shè)定為Intent.FLAG_ACTIVITY_SINGLE_TOP八毯。

沒什么區(qū)別,這里就只貼一份FirstActivity的代碼就好了瞄桨,其他類似话速。反正改變的都是四份代碼的里面的全部的點(diǎn)擊事件的Intent的addFlag從Intent.FLAG_ACTIVITY_NEW_TASK改成Intent.FLAG_ACTIVITY_SINGLE_TOP。

結(jié)論先上: ** 設(shè)定Intent.FLAG_ACTIVITY_SINGLE_TOP與清單文件里面指定 android:launchMode="singleTop"效果一致芯侥。**

操作:A打開B泊交,再打開(復(fù)用乳讥,無新實(shí)例),B打開C廓俭,再代開C(復(fù)用云石,無新實(shí)例),C打開D研乒,D再開D(復(fù)用汹忠,無新實(shí)例)

FirstActivity代碼


public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);

        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(FirstActivity.this, SecondActivity.class);

                openSecond.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(FirstActivity.this, ThirdActivity.class);

                openThird.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(FirstActivity.this, FourthActivity.class);

                openFourth.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(openFourth);
            }
        });

    }
}

情景3.gif

這里我們就不貼終端了。一個(gè)gif說明一切雹熬。

從圖中我們可以看到宽菜,(我們的B路星,C和D頁面都是每次打開的都是Intent.FLAG_ACTIVITY_SINGLE_TOP的)萌丈,當(dāng)我們打開頁面B,之后强挫,想再次打次B仰楚,就沒有新的實(shí)例產(chǎn)生了隆判,而是復(fù)用了頂部的B。
C和D也是這種情況發(fā)生僧界。圖中也做了演示侨嘀。

而且在最后,我們發(fā)現(xiàn)當(dāng)我們從A打開B捂襟,從B打開C咬腕,再從C打開D,最后D打開B的時(shí)候葬荷,就又可以打開B了涨共,又有一個(gè)B的實(shí)例產(chǎn)生并且位于棧頂了。所以這一切的一切都是跟xml設(shè)定launchMode為singleTop完全一致的宠漩。

證明結(jié)論:設(shè)定Intent.FLAG_ACTIVITY_SINGLE_TOP與清單文件里面指定 android:launchMode="singleTop"效果一致举反。

情景4 把A、B和C頁面的按鈕的打開頁面的Intent都不設(shè)置addFlag扒吁,即ABC打開的頁面都是standard火鼻,然后頁面D的打開頁面B的Intent的addFlag都設(shè)定的Intent.FLAG_ACTIVITY_CLEAR_TOP,其他兩個(gè)按鈕不設(shè)置Flag雕崩。

先上結(jié)論:
結(jié)論1:Intent.FLAG_ACTIVITY_CLEAR_TOP與清單文件里面指定 android:launchMode="singleTask"效果類似魁索,只是類似。因?yàn)楫?dāng)初頂部的時(shí)候和android:launchMode="singleTask"產(chǎn)生很大的差別
(參考情景5我們就知道是區(qū)別在哪里了)

結(jié)論2: 代碼指定Flag(不單指FLAG_ACTIVITY_CLEAR_TOP)盼铁,使得Activity啟動模式可變粗蔚,而且最后一次指定的Flag就是該Activity在任務(wù)棧中最終啟動模式。

這個(gè)上代碼吧饶火,因?yàn)楹竺孢€要描述一些事情支鸡。

FirstActivity

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);

        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(FirstActivity.this, SecondActivity.class);

                //openSecond.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(FirstActivity.this, ThirdActivity.class);

               
                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(FirstActivity.this, FourthActivity.class);

               
                startActivity(openFourth);
            }
        });

    }
}

.
.
SecondActivity

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);


        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(SecondActivity.this, SecondActivity.class);

                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(SecondActivity.this, ThirdActivity.class);


                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(SecondActivity.this, FourthActivity.class);

                startActivity(openFourth);
            }
        });
    }
}

.
.
ThirdActivity

public class ThirdActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);

        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(ThirdActivity.this, SecondActivity.class);


                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(ThirdActivity.this, ThirdActivity.class);


                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(ThirdActivity.this, FourthActivity.class);


                startActivity(openFourth);
            }
        });
    }
}

.
.
FourthActivity

public class FourthActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fourth);

        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(FourthActivity.this, SecondActivity.class);
                
                openSecond.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(FourthActivity.this, ThirdActivity.class);
   
                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(FourthActivity.this, FourthActivity.class);
         
                startActivity(openFourth);
            }
        });

    }
}

就是這樣冬念,其實(shí)目前只有在頁面D里面的用于打開頁面B的按鈕設(shè)置了Intent.FLAG_ACTIVITY_CLEAR_TOP的Flag

操作:我們啟動A,A啟動B牧挣,B啟動B急前,B再啟動C,C啟動D瀑构,再從D啟動B裆针。

分兩步走:

第一步:
我們啟動A,A啟動B寺晌,B再啟動C世吨,C啟動D,此時(shí)任務(wù)棧的里面的情況是DCBA呻征,其中D為棧頂耘婚。

    Running activities (most recent first):
      TaskRecord{52938abc #36 A=com.amqr.flagtest U=0 sz=4}
        Run #3: ActivityRecord{52978c64 u0 com.amqr.flagtest/.FourthActivity t36}
        Run #2: ActivityRecord{52946268 u0 com.amqr.flagtest/.ThirdActivity t36}
        Run #1: ActivityRecord{52a8fd24 u0 com.amqr.flagtest/.SecondActivity t36}
        Run #0: ActivityRecord{52a0a8b4 u0 com.amqr.flagtest/.FirstActivity t36}

第二步:再從D啟動B。
這時(shí)我們會發(fā)現(xiàn)陆赋,任務(wù)棧變成BA沐祷,其中B為棧頂,C和D都被B給干掉了攒岛。

    Running activities (most recent first):
      TaskRecord{52938abc #36 A=com.amqr.flagtest U=0 sz=2}
        Run #1: ActivityRecord{52969568 u0 com.amqr.flagtest/.SecondActivity t36}
        Run #0: ActivityRecord{52a0a8b4 u0 com.amqr.flagtest/.FirstActivity t36}

證明結(jié)論:Intent.FLAG_ACTIVITY_CLEAR_TOP與清單文件里面指定 android:launchMode="singleTask"效果類似赖临。(當(dāng)位于棧內(nèi)沒什么確實(shí)效果一致,當(dāng)位于棧頂就很不一樣了)

我們這里做了個(gè)實(shí)驗(yàn)灾锯。

我們看到代碼里我們的FirstActivity打SecondActivity的時(shí)候(就是A打開B的時(shí)候)兢榨,并沒有設(shè)定Intent的Flag,即A打開B的時(shí)候B在任務(wù)棧里面是屬于Standard模式的顺饮,但是在D打開B的時(shí)候吵聪,因?yàn)槲覀冎付ù蜷_B的時(shí)候B需要使用FLAG_ACTIVITY_CLEAR_TOP模式,所以這個(gè)時(shí)候就從Standard變成了FLAG_ACTIVITY_CLEAR_TOP(singleTask效果)了兼雄。

可見吟逝,代碼設(shè)定最大Flag好處就是啟動模式可變,而XML則是定死的君旦。

這里如果我們反過來,把上面代碼稍作修改嘲碱,把在A頁面打開B的時(shí)候把B設(shè)為FLAG_ACTIVITY_CLEAR_TOP金砍,然后D打開B不添加任何Flag(即為D打開的B為Standard),發(fā)現(xiàn)這樣設(shè)定之后麦锯,我們D打開B恕稠,結(jié)果是多產(chǎn)生了一個(gè)B的實(shí)例,而是不是B把D和C都給清掉扶欣。這就再一次證明最后設(shè)定開啟該Activity的模式其最終的啟動模式鹅巍。

結(jié)論證明 代碼指定Flag使得Activity啟動模式可變千扶,而且最后一次指定的Flag就是該Activity在任務(wù)棧中最終的模式。

情景5骆捧,把A打開B澎羞,B打開B的界面都設(shè)定為Intent.FLAG_ACTIVITY_CLEAR_TOP,然后A啟動B敛苇,B啟動B妆绞。

結(jié)論: 在一個(gè)打開時(shí)已經(jīng)被標(biāo)記為FLAG_ACTIVITY_CLEAR_TOP的界面(現(xiàn)正處于前臺任務(wù)棧的棧頂),如果我們在此界面打開自己枫攀,并且一樣標(biāo)記為FLAG_ACTIVITY_CLEAR_TOP括饶,那么這個(gè)時(shí)候會經(jīng)歷一次建新毀舊的過程,任務(wù)棧里面從結(jié)果的來說沒什么變化来涨,但是從生命周期的著眼于過程的角度來卻經(jīng)歷非常大的變化图焰。

步驟一:A打開B:

終端


    Running activities (most recent first):
      TaskRecord{52ac1a08 #61 A=com.amqr.flagtest U=0 sz=2}
        Run #1: ActivityRecord{529e1994 u0 com.amqr.flagtest/.SecondActivity t61}
        Run #0: ActivityRecord{529ca8e0 u0 com.amqr.flagtest/.FirstActivity t61}

生命周期

12-06 01:09:22.978 5768-5768/? D/Cur: FirstActivity  onCreate
12-06 01:09:22.978 5768-5768/? D/Cur: FirstActivity  onStart
12-06 01:09:22.978 5768-5768/? D/Cur: FirstActivity  onResume
// A打開B
12-06 01:09:25.694 5768-5768/com.amqr.flagtest D/Cur: FirstActivity  onPause
12-06 01:09:25.698 5768-5768/com.amqr.flagtest D/Cur: SecondActivity  onCreate
12-06 01:09:25.698 5768-5768/com.amqr.flagtest D/Cur: SecondActivity  onStart
12-06 01:09:25.698 5768-5768/com.amqr.flagtest D/Cur: SecondActivity  onResume
12-06 01:09:26.090 5768-5768/com.amqr.flagtest D/Cur: FirstActivity  onStop

在這里位置一切正常,下面發(fā)生的事情比較詭異

步驟二:B打開B蹦掐,這個(gè)是否發(fā)生的比較詭異技羔,不是復(fù)用,而是建立一個(gè)新的笤闯,毀滅舊的堕阔。

這里貼代碼非常有必要:
manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.amqr.flagtest" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".FirstActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".SecondActivity"
            />
        <activity android:name=".ThirdActivity"
            />
        <activity android:name=".FourthActivity"/>
    </application>

</manifest>

FirstActivity

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
        Log.d("Cur", "FirstActivity  onCreate");

        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(FirstActivity.this, SecondActivity.class);

                openSecond.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(FirstActivity.this, ThirdActivity.class);
                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(FirstActivity.this, FourthActivity.class);
                startActivity(openFourth);
            }
        });

    }


    @Override
    protected void onStart() {
        super.onStart();
        Log.d("Cur", "FirstActivity  onStart");
    }



    @Override
    protected void onResume() {
        super.onResume();
        Log.d("Cur", "FirstActivity  onResume");
    }


    @Override
    protected void onPause() {
        super.onPause();
        Log.d("Cur", "FirstActivity  onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("Cur", "FirstActivity  onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("Cur", "FirstActivity  onDestroy");
    }


    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("Cur", "FirstActivity  onRestart");
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d("Cur", "FirstActivity  onNewIntent");
    }
}

SecondActivity

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Log.d("Cur","SecondActivity  onCreate");


        findViewById(R.id.mBtOpen2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openSecond = new Intent(SecondActivity.this, SecondActivity.class);
                openSecond.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(openSecond);
            }
        });

        findViewById(R.id.mBtOpen3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openThird = new Intent(SecondActivity.this, ThirdActivity.class);
                startActivity(openThird);
            }
        });

        findViewById(R.id.mBtOpen4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openFourth = new Intent(SecondActivity.this, FourthActivity.class);
                startActivity(openFourth);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("Cur", "SecondActivity  onStart");
    }



    @Override
    protected void onResume() {
        super.onResume();
        Log.d("Cur", "SecondActivity  onResume");
    }


    @Override
    protected void onPause() {
        super.onPause();
        Log.d("Cur", "SecondActivity  onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("Cur", "SecondActivity  onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("Cur", "SecondActivity  onDestroy");
    }


    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("Cur", "SecondActivity  onRestart");
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d("Cur", "SecondActivity  onNewIntent");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.d("Cur", "SecondActivity  onSaveInstanceState");
    }
}

.
.

看完了代碼,我們先來看一下gif圖颗味。

詭異的FLAG_ACTIVITY_CLEAR_TOP.gif

當(dāng)我們在 B 界面打開B的時(shí)候超陆,根據(jù)的頁面的閃一下的反饋我們感覺這時(shí)候一個(gè)重新創(chuàng)建了B的一個(gè)實(shí)例,那么按道理任務(wù)這時(shí)候的情況就是BBA浦马,B為棧頂时呀,A為棧底,如果照著這種想法那么我們此時(shí)按下back鍵應(yīng)該是返回到B界面晶默,任務(wù)棧變成BA谨娜,B為棧頂。
但是實(shí)際上發(fā)生的卻不是這個(gè)樣子的磺陡,實(shí)際上發(fā)生的事情卻是:
按下back鍵趴梢,直接返回A界面。
再按一次back鍵就退出了程序了币他。

這意味著什么坞靶?這意味我們的眼睛欺騙了我們,屏幕閃的那一下是創(chuàng)建的一個(gè)B的實(shí)例沒有錯(cuò)蝴悉,但是我們看不到的事情是在新建新的實(shí)例入棧的同時(shí)那么舊的B就被銷毀掉了彰阴。所以,當(dāng)我們屏幕閃一下之后拍冠,任務(wù)棧存在的是BA尿这,B為棧頂簇抵,而不是BBA。

終端顯示的是每沒打開之前一樣射众,沒有變化(因?yàn)樗皇怯涗涀詈蟮慕Y(jié)果碟摆,不管過程)
(此時(shí)顯示的是B打開B之后的狀態(tài),還沒按下back)

    Running activities (most recent first):
      TaskRecord{52ac1a08 #61 A=com.amqr.flagtest U=0 sz=2}
        Run #1: ActivityRecord{52a0fb5c u0 com.amqr.flagtest/.SecondActivity t61}
        Run #0: ActivityRecord{529ca8e0 u0 com.amqr.flagtest/.FirstActivity t61}

從生命周期的變化我們大概明白這一切是怎么發(fā)生的了责球。


12-06 01:09:22.978 5768-5768/? D/Cur: FirstActivity  onCreate
12-06 01:09:22.978 5768-5768/? D/Cur: FirstActivity  onStart
12-06 01:09:22.978 5768-5768/? D/Cur: FirstActivity  onResume
//  A打開B
12-06 01:09:25.694 5768-5768/com.amqr.flagtest D/Cur: FirstActivity  onPause
12-06 01:09:25.698 5768-5768/com.amqr.flagtest D/Cur: SecondActivity  onCreate
12-06 01:09:25.698 5768-5768/com.amqr.flagtest D/Cur: SecondActivity  onStart
12-06 01:09:25.698 5768-5768/com.amqr.flagtest D/Cur: SecondActivity  onResume
12-06 01:09:26.090 5768-5768/com.amqr.flagtest D/Cur: FirstActivity  onStop

// B打開B  從生命周期我們發(fā)生了原因焦履,B在這里滅掉了自己,然后重建一個(gè)自己
12-06 01:11:50.390 5768-5768/com.amqr.flagtest D/Cur: SecondActivity  onPause
12-06 01:11:50.410 5768-5768/com.amqr.flagtest D/Cur: SecondActivity  onCreate
12-06 01:11:50.410 5768-5768/com.amqr.flagtest D/Cur: SecondActivity  onStart
12-06 01:11:50.410 5768-5768/com.amqr.flagtest D/Cur: SecondActivity  onResume
12-06 01:11:50.786 5768-5768/com.amqr.flagtest D/Cur: SecondActivity  onStop
12-06 01:11:50.786 5768-5768/com.amqr.flagtest D/Cur: SecondActivity  onDestroy

結(jié)論:設(shè)定為Intent.FLAG_ACTIVITY_CLEAR_TOP的Activity處于前臺任務(wù)棧棧頂時(shí)雏逾,如果在當(dāng)前頁面打開自己嘉裤,經(jīng)歷了一個(gè)建新毀舊的過程,算不上復(fù)用栖博。
(這個(gè)過程會創(chuàng)建一個(gè)新的實(shí)例屑宠,然后把舊的自己給銷毀掉,這個(gè)結(jié)果在任務(wù)棧的最終結(jié)果看來是沒變化的仇让,但是實(shí)際上生命周期卻發(fā)生了很大的變化典奉。)

結(jié)論:在一個(gè)打開時(shí)已經(jīng)被標(biāo)記為FLAG_ACTIVITY_CLEAR_TOP的界面(現(xiàn)正處于前臺任務(wù)棧的棧頂),如果我們在此界面打開自己丧叽,并且一樣標(biāo)記為FLAG_ACTIVITY_CLEAR_TOP卫玖,那么這個(gè)時(shí)候會經(jīng)歷一次建新毀舊的過程,沒有復(fù)用踊淳,任務(wù)棧里面從結(jié)果的來說沒什么變化假瞬,但是生命周期的著眼于過程的角度來卻經(jīng)歷非常大的變化。

本篇完迂尝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末脱茉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子垄开,更是在濱河造成了極大的恐慌琴许,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件溉躲,死亡現(xiàn)場離奇詭異榜田,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)锻梳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門箭券,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人唱蒸,你說我怎么就攤上這事邦鲫【牡穑” “怎么了神汹?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵庆捺,是天一觀的道長。 經(jīng)常有香客問我屁魏,道長滔以,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任氓拼,我火速辦了婚禮你画,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘桃漾。我一直安慰自己坏匪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布撬统。 她就那樣靜靜地躺著适滓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪恋追。 梳的紋絲不亂的頭發(fā)上凭迹,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機(jī)與錄音苦囱,去河邊找鬼嗅绸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛撕彤,可吹牛的內(nèi)容都是我干的鱼鸠。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼喉刘,長吁一口氣:“原來是場噩夢啊……” “哼瞧柔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起睦裳,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤造锅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后廉邑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哥蔚,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年蛛蒙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了糙箍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡牵祟,死狀恐怖深夯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤咕晋,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布雹拄,位于F島的核電站,受9級特大地震影響掌呜,放射性物質(zhì)發(fā)生泄漏滓玖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一质蕉、第九天 我趴在偏房一處隱蔽的房頂上張望势篡。 院中可真熱鬧,春花似錦模暗、人聲如沸禁悠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绷蹲。三九已至,卻和暖如春顾孽,著一層夾襖步出監(jiān)牢的瞬間祝钢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工若厚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拦英,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓测秸,卻偏偏與公主長得像疤估,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子霎冯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

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