Splash 閃屏頁流程與功能分析

0. 閃屏流程分析

要說到閃屏,幾乎已經(jīng)是所有 App 的標(biāo)配了。但是各家對于閃屏的理解和應(yīng)用方式各不相同。比如 Google 自己并不建議在閃屏頁中設(shè)置過長的停留時間,而只是作為冷啟動過程的一種變相緩沖,以就是僅在背景上設(shè)置一個 APP Logo 來避免屏幕留白。但在中國,幾乎所有的流量還不錯的 App 都會在閃屏頁中加入廣告,或者自己應(yīng)用中某個主題活動的宣傳,在增強(qiáng)品牌效應(yīng)。這其中又有不同的使用流派,但基本都可以歸為一個流程:

部分 App 會直接省略 Logo 這一環(huán),直接加載閃屏頁。觀察了幾個常用 App 后,我發(fā)現(xiàn)網(wǎng)易云音樂的閃屏邏輯是最好的,這不是說網(wǎng)易云音樂的閃屏流程與上面的圖片有什么不同,而是網(wǎng)易優(yōu)化了冷啟動過程。一般來說,App 在點(diǎn)擊 back 退出以后,再次打開會重新進(jìn)入冷啟動流程,也就是會再次進(jìn)入閃屏顯示流程,但是網(wǎng)易云音樂就不會:它只會在你第一次打開該 App 的時候加載 Loge 和 Splash,然后即使你按了 back 退出到屏幕,再次打開就不會再走閃屏流程了。這樣即使用戶多次退出打開也只會顯示一次 Splash 頁面,那么就算網(wǎng)易云的 Splash 時間稍微長一點(diǎn)你也不會在乎的吧(斜眼笑)。

1. 閃屏流程優(yōu)化

那么這種模式是如何實(shí)現(xiàn)的呢?開始我以為是因?yàn)槭峭ㄟ^檢測后臺服務(wù)是否運(yùn)行欄判斷是否跳過 splash 邏輯,但是我實(shí)際實(shí)驗(yàn)后發(fā)現(xiàn),這個方法雖然可行,但是在此打開時的頁面動畫就不是那么舒服了,有點(diǎn)生硬的感覺,而且不是所有的 App 都有后臺服務(wù)的。不管簡單的搜索就找到了我覺得正確的方式:

Activity 類中有一個方法:moveTaskToBack,接受一個 boolean 類型參數(shù),傳入 true 就會讓 App 退出進(jìn)入后臺,但是不會停止該進(jìn)程。這不就是我們想要的方式么?試了下果然跟網(wǎng)易云一毛一樣,這樣也是變相的避免了 App 冷啟動,減少了用戶的等待時間,提升了那么一點(diǎn)用戶體驗(yàn)吧。

除了這個方法還有另一種辦法:

  Intent intent = new Intent(Intent.ACTION_MAIN);
  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  intent.addCategory(Intent.CATEGORY_HOME);
  startActivity(intent);

效果與 moveTaskToBack 是相同的。

但是這兩個方法都有一個共同的弊端,如果 App 處于后臺超過一定時間沒有任務(wù)執(zhí)行也會被殺死的。而且這個時間非常短。我在自己手機(jī)上測試是 7 秒左右。不過這大概是因?yàn)槲沂謾C(jī)打開了某些清理工具的原因,畢竟寫在 onDestroy 里的 log 都沒打出來,可見是被強(qiáng)制殺死的。所以我又在虛擬機(jī)上測試了下,點(diǎn)擊返回以后等了三分鐘發(fā)現(xiàn)還是處于存活狀態(tài)我就沒有繼續(xù)測試了,基本已經(jīng)證明如果沒有第三方干涉,應(yīng)用應(yīng)該會在后臺存活較長時間,直到內(nèi)存不足被系統(tǒng)殺死。當(dāng)然作為一個有尊嚴(yán)的 App 應(yīng)該在用戶退出后開個定時器,十分鐘用戶還沒有回來就自毀吧,畢竟占著內(nèi)存不工作也不太好是吧。

不過相比于很多 App 用 再按一次返回退出 來挽留用戶,我覺得這種方式可能更加舒服一點(diǎn)。

2. 閃屏頁需求分析

首先要說的是,我這里所說的閃屏頁并不包括引導(dǎo)頁,這相對是另一個功能了。一般對閃屏而言,無外乎就這么幾個功能:

  • 顯示 Logo,增強(qiáng)品牌效應(yīng)
  • 打廣告,掙點(diǎn)零花錢
  • 內(nèi)部活動推廣,會帶有內(nèi)鏈

2.1 顯示 Logo

首先說顯示 Logo,如果 App 的 Logo 與開始的圖片上的流程是一樣的,那么 Logo 是可以有兩種方式來顯示的。

  1. 通過 windowBackground 來設(shè)置:可以在屏幕背景里放一個非全屏顯示的圖片,作為打開的留白的間隙的替代,當(dāng)正常內(nèi)容加載完就會被覆蓋掉。Logo 的顯示時間取決于正常內(nèi)容的加載時間,如果加載很快,Logo 就會一閃而過。但為什么是非全屏顯示呢,對于 windowBackgroung,很難設(shè)置圖片的拉伸模式,那么屏幕適配就非常麻煩。所以放一個非全屏圖片,設(shè)置個背景色或許是個不錯的選擇。這種方式也是 Google Photos 在用的。至于一閃而過對于用戶的體驗(yàn)是否良好就仁者見仁了。另外值得一提的是網(wǎng)易云應(yīng)該也是使用這種方式,因?yàn)?Logo 的顯示時間并不總是相同而且沒有絲毫的留白間隙,但是它的 Logo 是全屏的,這就得佩服下網(wǎng)易的技術(shù)水平了(微笑臉)。

  2. 除了這種方式就是常規(guī)的用一個單獨(dú)的頁面來顯示 Logo 了,這種沒什么好說的,全屏往里面放圖片就行了。

2.2 顯示廣告

然后說打廣告,這里的廣告是指接的外部廣告,比如網(wǎng)易的閃屏經(jīng)常會放某某車的廣告,或者天貓什么節(jié)的,還是有很酷炫的動畫和聲音的那種,簡單的圖片動態(tài)加載比較簡單,但是帶有多媒體效果的廣告就略復(fù)雜了,這里就只說動態(tài)下拉圖片廣告吧。

動態(tài)下拉圖片廣告需要后臺 API 的配合。比如檢測是不是要下載新的廣告,廣告的過期時間,緊急停用某個廣告等。因?yàn)槲也皇呛笈_,所以自己寫了個簡單的后臺廣告接口,勉強(qiáng)夠用:

  • 請求
    • 地址:
    • 方法:GET
    • 格式:<K,V>
    • 參數(shù):
      • Long : splashId //當(dāng)前 splash id,為空則返回最新 splash 信息
  • 返回
    • 數(shù)據(jù):閃屏信息
    • 格式:json
    • 例子:
      {
          "splash":
          {
              "id":1,                 //閃屏識別 id
              "imgUrl":"",            //閃屏圖片下載地址
              "eventUrl":"",          //閃屏活動地址
              "eventTitle":"",        //閃屏活動標(biāo)題
              "deadDate":0,           //有效期至(Long 毫秒值)
              "disable":true          //是否停用,用于緊急下線閃屏
          }
      }
      
    • 服務(wù)器行為:
      • 根據(jù) id 檢查是否存在新的 splash 信息,存在則返回 splash 對象,不存在返回空,停用該 splash 則返回 id 相同、 disable=true 的 splash 對象

如果 App 某段時間內(nèi)只維持一個 Splash,也就是顯示同一個廣告,那么對象信息可以存在 SP 里,如果要維持多個 Splash,那還是單獨(dú)建個數(shù)據(jù)表來存儲比較方便。我這個接口只適合維持一個 Splash,因此也不存在考慮顯示頻次的問題,如果要適配多 Splash 的需求,我想你們肯定能做到的(斜眼笑)。

對移動端來說,每次打開 App 都要請求該接口,以保證 Splash 的最新。當(dāng)發(fā)送 id 與接收到的 id 不同,那么就要開啟子線程與下載新的 Splash 圖片了。如果相同,但 disable=true,下次冷啟動就不會再顯示這個 Splash 了。

2.3 顯示活動推廣

本來我以為只有 App 自己的活動推廣才會帶有內(nèi)鏈,不過網(wǎng)易顯然又刷新了我的認(rèn)知,它竟然在網(wǎng)易云里面加載天貓某某節(jié)的頁面!不愧是網(wǎng)易,果然有態(tài)度。其實(shí)看上一小節(jié)的 API 文檔,就知道 Splash 里還帶有兩個 url 屬性的,imgUrl 是廣告圖片的下載地址,eventUrl 是活動頁面地址,至于 eventTitle 就是活動頁面的標(biāo)題了。

這個其實(shí)只要給 Splash 圖片設(shè)置個點(diǎn)擊事件就行了,不過有一點(diǎn)還是要說下:點(diǎn)擊圖片進(jìn)入了活動頁面,如果 Splash 頁面已經(jīng) finish 掉了,那么 App 不是就直接退出了么,如果推廣是給別家推廣的,有種給別人做了嫁衣裳的感覺啊。因此,對于活動頁面的退出,還得加一層判斷邏輯??紤]到內(nèi)鏈不僅會是 web 頁面,也可能是內(nèi)部的某個常規(guī) Activity,因此需要在所有可能由 Splash 跳轉(zhuǎn)而來的頁面里進(jìn)行判斷:

首先在開啟 Activity 的傳入?yún)?shù):

    public static void actionStart(Context context, String url, String title, boolean isFromSplash) {
        Intent intent = new Intent(context, CommonWebActivity.class);
        intent.putExtra("url", url);
        intent.putExtra("title", title);
        intent.putExtra("isFromSplash", isFromSplash);
        context.startActivity(intent);
    }

然后在需要做退出判斷的地方:

    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {//優(yōu)先讓內(nèi)置瀏覽器返回至上一頁
            webView.goBack();
        } else if (isFromSplash) {//如果從閃屏跳轉(zhuǎn)而來,則關(guān)閉返回至首頁
            MainActivity.actionStart(this);
        } else {
            super.onBackPressed();
        }
    }

如果你有抽取 BaseActivity,那么在 BaseActivty 中判斷更好:

    @Override
    public void onBackPressed() {
        if (isFromSplash) {//如果從閃屏跳轉(zhuǎn)而來,則關(guān)閉返回至首頁
            MainActivity.actionStart(this);
        } else {
            super.onBackPressed();
        }
    }

至此,閃屏的分析就結(jié)束了,一般來說 Splash 頁面就這么些功能了,這里我沒有貼上完整的實(shí)現(xiàn)代碼,因?yàn)闇y試 API 是用 SpringBoot 建的,而且大家的后臺并不一定是自己可以控制的,因此主要還是提供個思路,具體的實(shí)現(xiàn)方式還是要因公司(需求)而異。

本文最早發(fā)布于 alphagao.com.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,034評論 25 709
  • 最近在整理做產(chǎn)品以來收集到的各種資料,準(zhǔn)備針對app的常見功能模塊總結(jié)下經(jīng)驗(yàn),一來加深學(xué)習(xí)效果,二來供大家學(xué)習(xí)交流...
    jason_peng閱讀 1,826評論 0 22
  • 前幾天看到一個觀點(diǎn),深以為然。一個人要在某個領(lǐng)域做到領(lǐng)先很難,但是做到前四分之一并不是特別難。然后在另外一個領(lǐng)域也...
    chinawzck閱讀 155評論 0 1
  • 為你踏泥折竹 -亞平 從姥姥家...
    過好一生閱讀 273評論 0 0
  • 我總想撥一個電話 問你還好嗎?怎么樣啊? 可是,我撥了又掛 我恐,你又哭了...
    風(fēng)在搖曳閱讀 250評論 0 2

友情鏈接更多精彩內(nèi)容