首頁  >  文章  >  微信小程式  >  一起看看 Activity啟動模式

一起看看 Activity啟動模式

coldplay.xixi
coldplay.xixi轉載
2020-12-10 17:10:452825瀏覽

小程式開發教學主要介紹了Activity啟動模式的相關資料

一起看看 Activity啟動模式

#推薦(免費):小程式開發教學

前言

#平常我們啟動活動的時候就是直接startActivity或許並沒有註意活動的啟動模式,預設狀況下都是以預設的啟動模式啟動。但啟動模式有時候是比較重要的。例如一個活動你想他只啟動一次不要有多個實例,那你可能需要把他設定為singleTask模式。所以有必要了解這一些啟動模式。同時要注意一下,啟動模式≠啟動方式,啟動方式是指顯示啟動和隱式啟動,不要混淆,顯示啟動和隱式啟動後續我會有專門的文章講解。

關於任務堆疊簡介

要了解啟動模式,首先要了解關於任務堆疊的概念。關於任務棧的實作原理等我在這裡就先不說了,這裡主要簡單介紹一下什麼是任務棧。我們啟動的活動實例都會放在一個叫做任務棧的東西裡面。我們都知道棧是「後進先出」的特徵。打個比方,任務棧就是一個羽球筒,活動實例就是一個羽毛球,後放進去的只能先拿出來。所以當我們啟動一個app的時候,就會自動建立一個任務棧,然後我們就往裡面丟活動實例。當我們按返回銷毀活動的時候,這些活動就依序從任務堆疊裡面出來。當然,app可以擁有多個任務棧,例如使用singleInstence啟動的活動就是在一個獨立的任務棧。了解完任務堆疊的概念,接下來就可以來看看活動的四種啟動模式。

解析Activity的四個啟動模式

standard

#這個是標準啟動模式,預設就是這種啟動模式。每次啟動這種啟動模式的活動的時候都會建立一個新的實例放入堆疊中,不管堆疊中是否已經存在相同的實例。這也是最容易理解的。

singleTop

顧名思義,堆疊頂端是單一實例的。什麼意思呢。假設你現在啟動一個ActivityA,但這個時候已經存在一個ActivityA實例在堆疊頂,那麼這個時候,就不會建立新的實例。但是如果,在非棧頂存在相同的實例,還是會建立新的實例的。例如,現在棧中的活動是 ABC,A處於棧頂。然後此時啟動A,是不會再創建一個A活動出來,而是執行A的onNewIntent方法;但是如果此時啟動C活動,由於棧頂是A不是C,那麼還是會創建一個新的C實例出來,此時的棧情況就是CABC。

singleTask

單一任務模式。這個模式的意思是,在該活動的啟動堆疊中,只能存在單一實例,不管是否位於堆疊頂端。與其他啟動模式不同的是,這個啟動模式可以指定堆疊去啟動。例如現在有一個棧Main,但是你可以給活動A指定一個棧名dev,那麼啟動A的時候就會建立一個棧叫做dev。所以singleTask的意思是,當你啟動一個啟動模式為singleTask的活動的時候,如果棧中沒有相同的實例,那麼就會創建一個新的實例放入棧中;如果指定棧中存在相同的實例,例如棧中有ABC,然後你啟動B,那麼這個時候不會去創建新的B實例,而是把B放到棧頂,並把A頂出去,再執行B的onNewIntent方法,此時棧的情況就是BC。
細心的讀者會發現「頂出去」。是的,我們都知道棧是後進先出的特點,例如你往筒裡放了3個羽毛球,那你想要拿到中間那個羽毛球,是不是只能先把上面那個抽出來呢,同樣的道理,要想把B提到棧頂,那就必須把A頂出來。可能會有很多讀者誤以為啟動後是BAC,但其實是BC,因為A得先出棧,B才能出來。同理,如果棧中是ADFBC,這個啟動B,也是BC,上面的全部被出棧了。

singleInstance

單例模式。這個是singleTask的強化版本。他會自己新建一個堆疊並把這個新的實例放進去,而且這個堆疊只能放這個活動實例。所以當重複啟動這個活動的時候,只要他存在,都是呼叫這個活動onNewIntent方法並切換到這個堆疊中,並不會去建立新的實例。

設定啟動模式的兩種方法

了解了活動的四種啟動模式,接下來看看如何為他指定啟動模式。

靜態設定

靜態設定就是在AndroidManifest中給特定活動設定啟動模式。透過給活動指定launchMode參數來設定啟動模式。例如:

 

動態設定

動態設定是在啟動活動的時候再指定啟動模式,例如:

Intent intent = new Intent();
intent.setClass(this,SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

可以看到我们通过intent.addFlags这个方法来指定启动模式,这个方法传入一个参数来指定启动模式,其他的参数有:

  • FLAG_ACTIVITY_NEW_TASK:singleTask模式
  • FLAG_ACTIVITY_SINGLE_TOP:singleTop模式
  • FLAG_ACTIVITY_CLEAR_TOP:清除该活动上方的所有活动。一般和singleTask一起使用。但是如果你的启动模式是standard,那么这个活动连他之上的所有活动都会被出栈再创建一个新的实例放进去。例如现在栈中是ABCD,以FLAG_ACTIVITY_CLEAR_TOP+standard模式启动C的时候,首先清理掉ABC,是的,C也会被清理,然后再创建一个新的C放进去,执行之后就是CD。

特别注意的坑

singleInstance返回任务栈

现在模拟一个场景:现在有三个活动 A,B,C。A和C的启动模式都是standard,B的启动模式是singleInstance。先启动A,再启动B,然后再启动C。这个时候问题来了,如果我这个时候按下返回键,是回到B吗?答案是回到A。再按一下呢,返回桌面吗?答案是回到B,再按一下再回到桌面。其实不难理解。我们都知道singleInstance会创建一个独立的栈,当我们启动A的时候,A位于栈First中,启动B的时候,就会创建一个栈Second并把B实例放进去。这个时候再启动C,就会切换到栈FIrst,因为singleInstance创建的栈只能放一个,所以C会放到栈First中,当按下返回的时候,栈First中的活动就会依次出栈,直到全部出完,才会切换到栈Second中。所以要注意这个点。

singleTask多任务栈启动问题

这个问题和上面singleTop的本质是一样的。模拟一个场景:现在有两个栈:First:ABC;Second:QWE。栈First位于前台,栈Second位于后台。A位于栈顶。这个时候以singleTask的模式启动W,会发生什么样的情况呢?首先会切换到栈Second,再把Q出栈,W提到栈顶,并执行W的onNewIntent方法。这个时候按返回键就会把Second栈中的活动依次出栈,全部出完后才会切换到栈First。

singleTask的TaskAffinity与allowTaskReparenting参数

前面我们讲到给singleTask模式指定要启动的任务栈的名字,怎么指定呢?可以在AndroidManifest中指定相关的属性,如下:

这里解释一下这两个参数

  • taskAffinity:指定任务栈的名字。默认的任务栈是包名,所以不能以包名来命名。
  • allowTaskReparenting:这个参数表示可不可以切换到新的任务栈,通常设置为true并和上面的参数一起使用。

我前面讲到可以给singleTask的活动指定一个栈名,然后启动的时候,就会切换到那个栈,并把新的活动放进去。但是如果设置allowTaskReparenting参数为false的话是不会切换到新的栈的。这个参数的意思是可不可以把新的活动转移到新的任务栈。简单点来说:当我们启动一个singleTask活动的时候,这个活动还是留在启动他的活动的栈中的。但是我们指定了taskAffinity这个参数,或者启动的活动是别的应用中的活动,那么就会创建一个新的任务栈。如果allowTaskReparenting这个参数是true的话,那么这个活动就会放到那个新的任务栈中。这样应该就可以明白了。所以这两个经常是配套一起使用的。

总结

活动的启动模式有四种,每种的功能都不一样,可以结合具体需要去使用,但是最重点还是要了解他的实现原理,栈中是怎么变化的,这个是比较重要的。了解这个之后那些特殊情况也就很容易理解了。
上面我讲的只是简单的使用,关于活动启动模式还有很多要了解。后续可能会解析一下,读者也可以自行去深度了解。

相关免费推荐:编程视频课程

以上是一起看看 Activity啟動模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:jb51.net。如有侵權,請聯絡admin@php.cn刪除