主頁 > 移動端開發 > 探究 | App Startup真的能減少啟動耗時嗎

探究 | App Startup真的能減少啟動耗時嗎

2020-12-22 10:35:57 移動端開發

前言

之前我們說了啟動優化的一些常用方法,但是有的小伙伴就很不屑了:

“這些方法很久之前就知道了,不知道說點新東西?比如App Startup?能對啟動優化有幫助嗎?”

ok,既然你誠心誠意的發問了,那我就大發慈悲的告訴你:俺也不知道??

走吧,一起瞅瞅這個App Startup吧,是不是真的能給我們的啟動帶來優化呢?

(想看結果的可以直接跳到最后的實踐總結階段)

Contentprovider中初始化

想必大家都了解,很多三方庫都需要在Application中進行初始化,并順便獲取到Application的背景關系,

但是也有的庫不需要我們自己去初始化,它偷偷摸摸就給初始化了,用到的方法就是使用ContentProvider進行初始化,定義一個ContentProvider,然后在onCreate拿到背景關系,就可以進行三方庫自己的初始化作業了,而在APP的啟動流程中,有一步就是要執行到程式中所有注冊過的ContentProvider的onCreate方法,所以這個庫的初始化就默默完成了,

這種做法確實給集成庫的開發者們帶來了很大的便利,現在很多庫都用到了這種方法,比如Facebook,Firebase,這里拿Facebook舉例看看他的ContentProvider:

    <provider
        android:name="com.facebook.internal.FacebookInitProvider"
        android:authorities="${applicationId}.FacebookInitProvider"
        android:exported="false" />
public final class FacebookInitProvider extends ContentProvider {
    private static final String TAG = FacebookInitProvider.class.getSimpleName();

    @Override
    @SuppressWarnings("deprecation")
    public boolean onCreate() {
        try {
            FacebookSdk.sdkInitialize(getContext());
        } catch (Exception ex) {
            Log.i(TAG, "Failed to auto initialize the Facebook SDK", ex);
        }
        return false;
    }

    //...
}

可以看到,在Fackbook的sdk中,定義了一個FacebookInitProvider,并且在onCreate中進行了初始化,所以我們才無需單獨對Facebook的sdk進行初始化,

雖然更方便了,但是這種做法有給啟動優化帶來什么好處嗎?我們一起再回顧下之前的啟動流程研究下,截取一部分:

  • ...
  • attachBaseContext
  • Application attach
  • installContentProviders
  • Application onCreate
  • Looper.loop
  • Activity onCreate,onResume

這其中installContentProviders方法就是用來啟動并執行各個ContentProvideronCreate方法的,它會在ApplicationonCreate方法之前執行,

所以這些庫只是把Application的三方庫初始化作業提前放到ContentProvider中了,并不會減少啟動耗時,反而會增加啟動耗時,

怎么說呢?因為不同的庫就定義了不同的ContentProvider類,多了這么多ContentProviderContentProvider作為四大組件之一,啟動也是耗時的,自然也就增加App啟動消耗的時間了,

這時候就需要App Startup來對此情況進行優化了~

官網簡介

The App Startup library provides a straightforward, performant way to initialize components at application startup. Both library developers and app developers can use App Startup to streamline startup sequences and explicitly set the order of initialization.Instead of defining separate content providers for each component you need to initialize, App Startup allows you to define component initializers that share a single content provider. This can significantly improve app startup time.

主要說了兩點特性:

  • 可以共享單個Contentprovider,
  • 可以明確地設定初始化順序,

可以共享單個Contentprovider

這一點功能就能解決剛才的問題了,不同的庫不再需要去啟動多個Contentprovider了,而是共享同一個Contentprovider

這樣就至少不會增加啟動耗時了,

怎么操作呢?假如我們是FacebookSDK設計者,我們就來改一下剛才的FacebookSDK,集成App Startup

//匯入庫
implementation "androidx.startup:startup-runtime:1.0.0"


// Initializes facebooksdk.
class FacebookSDKInitializer : Initializer<Unit> {
    private  val TAG = "FacebookSDKInitializer"

    override fun create(context: Context): Unit {
        try {
            FacebookSdk.sdkInitialize(context)
        } catch (ex: Exception) {
            Log.i(TAG, "Failed to auto initialize the Facebook SDK", ex)
        }
    }

    
    override fun dependencies(): List<Class<out Initializer<*>>> {
        return emptyList()
    }
}


//AndroidManifest.xml中定義
<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">

    <meta-data  android:name="com.example.FacebookSDKInitializer"
          android:value="https://www.cnblogs.com/jimuzz/p/androidx.startup" />
</provider>

實作了Initializer介面,然后在onCreate方法中進行初始化即可,只要所有的庫都按照這個標準來初始化,而不是自己單獨自定義ContentProvider,那么確實可以減少啟動耗時,

其中,tools:node="merge"標簽就是用來合并所有申明了InitializationProviderContentProvider

等等,Initializer介面還有一個方法dependencies,這又是干啥的呢?

可以明確地設定初始化順序

這也就是App Startup的第二個特性了,可以設定初始化順序,

可以想象,按照上述做法,所有庫都這樣設定了,那么都會在同一個ContentProvider也就是androidx.startup.InitializationProvider中初始化,但是如果我需要設定不同庫的初始化順序怎么辦呢?

比如上述的facebook初始化,我需要設定在另一個庫WorkManager之后運行,那么我們就可以重寫dependencies方法:

class FacebookSDKInitializer : Initializer<Unit> {
    private  val TAG = "FacebookSDKInitializer"

    override fun create(context: Context): Unit {
        try {
            FacebookSdk.sdkInitialize(context)
        } catch (ex: Exception) {
            Log.i(TAG, "Failed to auto initialize the Facebook SDK", ex)
        }
    }

    
    override fun dependencies(): List<Class<out Initializer<*>>> {
        return listOf(WorkManagerInitializer::class.java)
    }
}

不錯吧,這樣設定之后,三方庫的初始化順序就變成了:

WorkManager初始化 -> FacebookSDK初始化,

實踐出真理

說了這么多,從理論上來說,確實App Startup減少了耗時,畢竟將多個ContentProvider融合成了一個,那么我們秉著“實踐才是檢驗真理的唯一標準”,就來實踐看看耗時減少了多少,

該怎么統計這個啟動時間呢?一般有以下幾個方案:

  • 如果是Application和Activity的時間可以通過TraceView、systrace等 的方式進行時間統計,但是ContentProvider的初始化在Application之前,不適用我們這次實踐,

  • Android官方提供了一個可以統計線上應用啟動時間的工具——Android Vitals,它可以在GooglePlay管理中心顯示應用啟動過長情況的啟動時間,很顯然這個也不適用于我們,這個必須上線到Googleplay

  • 視頻錄制,如果是線下的app,我們可以采用視頻錄制的方法準確測量啟動時間,也就是通過判定視頻的每一幀截圖來知曉什么時候app啟動了,然后統計這個啟動時間,具體做法就是使用adb shell screenrecord命令進行螢屏錄制然后分析視頻,有興趣的小伙伴可以網上找找資料,這里就不細說了,

  • 最后,就是用系統自帶的統計時間TotalTime

這個時間是Android原始碼中幫我們計算的,可統計到Activity的啟動時間,如果我們在Home頁執行命令,也就能得到一個冷啟動的時間,雖然這個時間不是很準確,但是我只需要比較App StartUp使用的的前后時間大小,所以也夠用了,開干,

1)測驗2個ContentProvider

第一次,我們測驗2個ContentProvider的情況,

        <provider
            android:name=".appstartup.LibraryAContentProvider"
            android:authorities="${applicationId}.LibraryAContentProvider"
            android:exported="false" />

        <provider
            android:name=".appstartup.LibraryBContentProvider"
            android:authorities="${applicationId}.LibraryBContentProvider"
            android:exported="false" />

安裝到手機后,打開應用,Terminal中輸入命令:

adb shell am start -W -n packagename/packageName.MainActivity

由于每次啟動時間不一,所以我們運行五次,取平均值:

TotalTime: 927
TotalTime: 938
TotalTime: 948
TotalTime: 934
TotalTime: 937

平均值:936.8

然后注釋剛才的ContentProvider注冊代碼,添加App startup代碼,并注冊:

        <provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            android:exported="false"
            tools:node="merge">

            <meta-data  android:name="com.example.studynote.appstartup.LibraryAInitializer"
                android:value="https://www.cnblogs.com/jimuzz/p/androidx.startup" />

            <meta-data  android:name="com.example.studynote.appstartup.LibraryBInitializer"
                android:value="https://www.cnblogs.com/jimuzz/p/androidx.startup" />
        </provider>

運行App,并執行命令,得出啟動時間:

TotalTime: 931
TotalTime: 947
TotalTime: 937
TotalTime: 940
TotalTime: 932

平均值:937.4

咦??我手機壞了嗎?怎么跟預想的不一樣啊,結果耗時還增加了?

按道理來說原來有兩個ContentProvider,用了App startup,集成為一個,耗時不應該減少么,

其實這就涉及到ContentProvider的實際耗時了,我在網上找到一張圖,關于ContentProvider耗時,是Google官方做的統計,圖片來源于郭神的博客:

可以看到這里統計的1個ContentProvider耗時2ms左右,10ContentProvider耗時6ms左右,

所以我們只減少了一個ContentProvider的耗時,幾乎可以忽略不計,再加上我們用到的App Startup庫中InitializationProvider的一些任務也會產生耗時,比如:

  • 會去遍歷所有metadata標簽的組件
  • 會通過反射獲取每個組件的Initializer介面,并獲取相應的依賴項,并進行排序

這些操作也是耗時的,也就是集成App Startup庫之后增加的耗時時間,所以就有可能會發生上面的情況了,集成App Startup庫之后啟動耗時反而增多,

那難道這個庫就沒用了嗎?肯定不是的,當ContentProvider的數量變多,它的作用就體現出來了,再試下10個ContentProvider的情況,

2)10個ContentProvider

首先寫好10個ContentProvider,并在AndroidManifest.xml中注冊:

        <provider
            android:name=".appstartup.LibraryAContentProvider"
            android:authorities="${applicationId}.LibraryAContentProvider"
            android:exported="false" />

<!--      省略剩下9個provider注冊代碼        -->

運行五次,取平均值:

TotalTime: 1758
TotalTime: 1759
TotalTime: 1733
TotalTime: 1737
TotalTime: 1747

平均值:1746.8

然后注釋剛才的ContentProvider注冊代碼,添加App startup代碼,并注冊:

        <provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            android:exported="false"
            tools:node="merge">

            <meta-data  android:name="com.example.studynote.appstartup.LibraryAInitializer"
                android:value="https://www.cnblogs.com/jimuzz/p/androidx.startup" />

            <!--省略剩下9個meta-data注冊代碼-->
        </provider>

運行App,并執行命令,得出啟動時間:

TotalTime: 1741
TotalTime: 1755
TotalTime: 1722
TotalTime: 1739
TotalTime: 1730

平均值:1737.4

可以看到,這里App Startup的作用就體現了出來,在使用App Startup之前的啟動耗時是1746.8ms,使用之后啟動耗時是1737.4ms,減少了9.4ms

所以得出結論,當集成的庫使用的ContentProvider達到一定個數之后,確實能減少耗時,但是減少的不多,比如這里我們是10個ContentProvider集成App Startup后能減少的耗時在10ms左右,再結合上圖官方的統計時間來看,一般一個專案集成了十幾個使用ContentProvider的庫,耗時減少應該能在20ms之內,

所以我們的App Startup解決的就是這個耗時時間,雖然不多,但是也確實有減少耗時的功能,

思考

雖然這個庫能解決一定的三方庫初始化耗時問題,但是我覺得還是有很大的局限性,比如這些問題:

  • 本身依賴的庫就不多,如果我們的專案本身依賴就不多,那么有沒有必要去集成這個呢?極端情況下,只依賴了一個庫,那么還要專門提供一個InitializationProvider,是不是又變相的增加了耗時呢?
  • 延時初始化,上次我們說過,有些庫并不需要一開始就初始化,那么我們最好將其延遲初始化,進行懶加載,
  • 異步初始化,同樣,有些庫不需要在主執行緒進行初始化,那么我們可以對其進行異步初始化,從而減少啟動耗時,
  • 多個異步任務依賴關系,如果有些任務需要異步執行的同時還有互相的依賴關系,該怎么辦呢,

如果我們在使用App Startup的時候,有以上需求,那么有沒有解決辦法呢?

  • 沒有,也可以說有,就是關閉App Startup的初始化動作,然后自己進行初始化任務管理,

這可不是開玩笑,App Startup的目的只是解決一個問題,就是多個ContentProvider創建的問題,通過一個統一的ContentProvider來形成規范,減少耗時,所以它的用法應該是針對各個三方庫的設計者,當你設計一個庫的時候,如果想靜默初始化,就可以接入App Startup,當盡量多的庫遵循這個要求,都接入App Startup的時候,開發者的啟動耗時自然就降低了,

但是如果我們有其他的需求,比如上述說到的延遲初始化,異步初始化等問題,我們就要關閉部分庫或者所有庫的App Startup的功能,然后自己單獨對任務進行初始化作業,比如通過啟動器來處理各個初始化任務的關系,

如果一個庫已經集成了App Startup功能,我們該怎么關閉呢?這就用到tools:node="remove"標簽了,

<!-- 禁用所有InitializationProvider組件初始化 -->
<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove" />


<!-- 禁用單個InitializationProvider組件初始化 -->
<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">

    <meta-data  android:name="com.example.FacebookSDKInitializer"
            android:value="https://www.cnblogs.com/jimuzz/p/androidx.startup"
            tools:node="remove"/>
</provider>

這樣FacebookSDK就不會自動進行初始化了,需要我們手動呼叫初始化方法,

總結

1)App Startup的設計是為了解決一個問題:

  • 即不同的庫使用不同的ContentProvider進行初始化,導致ContentProvider太多,管理雜亂,影響耗時的問題,

2)App Startup具體能減少多少耗時時間:

  • 上面也實踐過了,如果二三十個三方庫都集成了App Startup,減少的耗時大概在20ms以內,

3)App Startup的使用場景應該是:

  • 針對三方庫的設計者或者組件化的場景,當你設計一個庫或者一個組件的時候,就可以接入App Startup,當盡量多的庫遵循這個標準,都接入App Startup的時候,就能形成一種規范,App的啟動耗時自然就降低了,

4)如果想解決多個庫初始化任務太多導致的啟動耗時問題:

  • 請左轉前往各種啟動器,比如alibaba/alpha

參考

Google檔案

App Startup-郭霖

Android啟動時間—siyu8023

App Startup原始碼—葉志陳

拜拜

有一起學習的小伙伴可以關注下?? 我的公眾號——碼上積木,每天剖析一個知識點,我們一起積累知識,公眾號回復111可獲得面試題《思考與解答》以往期刊,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/238474.html

標籤:Android

上一篇:哪位大神指導為什么y獲取到的值是空,n的值是對的??

下一篇:探究 | App Startup真的能減少啟動耗時嗎

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more