1. 程式人生 > >App競品技術分析 (3)減小安裝包的體積

App競品技術分析 (3)減小安裝包的體積

1 從幾件小事說起

  春節在家幫姐姐的iPhone手機安裝市面上形形色色的App,忘記她是使用4G流量包月了,於是在下載了10個App後,不但耗盡了流量,還按照0.3元/兆的價格扣了七八十元流量費用。後來我檢查了這幾個App的體積,發現每個App體積都是40-50M的樣子,這讓我很吃驚,因為我記得兩年前這些App也就在10-20M的樣子。

  另一件記憶猶新的事情,是去公園景點遊玩,當時公園門口有個活動“掃二維碼下載App下單立減10元”,但是我發現下載這個40M的App要花費12元的流量,這樣其實是要額外多花2元錢,所以“掃碼立減”這件事情對於我這種小市民而言是很不划算的。

  由此而得到一個結論,App安裝包的體積一定要小,至少要比競爭對手的App體積小。

  對於Android而言,國內的各大市場商店已經發現這個問題了,所以對於使用者升級App,會為每個App提供增量下載的功能,所以App版本升級不再是幾十M的流量,而只是下載1-2M的增量包就能升級到最新版本,這樣就極大節省了流量。[1]

  對於iOS而言,AppStore從iOS6開始提供增量更新功能。對於iOS 6.x和iOS7.0,只要有檔案改動過,這個檔案就會進入到增量更新包中,比如說1個10M的檔案,只改動了1KB的內容,這個10M檔案就會進入到增量更新包中,包還是很大。到了iOS7.1及更高版本,這個機制進行了改良,它會把這1KB的改動內容放到增量更新包中,從而極大的減少了增量更新包的大小,但是安裝的時候會變慢,因為要把這1KB的改動內容合併到10M檔案中,這是個很繁瑣很費時的工作。[2]

  儘管如此,以上種種措施只能解決升級使用者的流量困擾,對新使用者並無幫助。我們必須減小安裝包的大小,才能吸引更多的新使用者。

2 安裝包為什麼那麼大

  是什麼讓App安裝包的體積變得如此之大?

  我們在前面的章節看到了iOS和Android安裝包的內部結構,對於可執行檔案,我們無能為力;對於XML檔案,這些檔案在App打包壓縮後會極大減小體積,所以也不用管它們;那麼就只能在圖片和音訊檔案上做文章了。

  各位讀者看到這裡,都請停下手中的工作,檢查一下自家App包中圖片和音訊檔案的大小。圖片但凡是大於1M的,都是需要瘦身的。對於500KB-1M這個區間內的,也有瘦身的可能。我研究過很多知名的App,其中有很多圖片都在2-3M的樣子,其實真沒有必要,之所以這麼大,是因為UI設計人員提供的設計稿就是這麼大,開發人員拿過來也不看檔案體積大小直接就往專案裡放,久而久之,App包的體積就大了。

  在眾多App之中,我印象最深的是一款旅遊類軟體,它的所有圖片都不超過100KB,甚至說50KB以上的都屈指可數。這是把極致做到家的表現。

  接下來說音訊檔案,對於應用類App而言,我見到的大都是App推送時發出的聲音,這個聲音很簡單,不應該超過10KB。但我在很多App中看到的音訊,都在100KB左右。這是我們優化的一個方向。網上有很多這樣的軟體,可以對音訊進行大幅壓縮。

3 png和jpg的區別和使用場景

  設計師曾經問過我,App為什麼不使用jpg圖片,因為同樣的尺寸,png格式的圖片要比jpg圖片大很多。

  眾所周知,png有透明通道,而jpg沒有,此外png是無失真壓縮的而jpg是有失真壓縮的,所以png中儲存的資訊會很多,體積自然就大了。

  但是手機卻偏偏對png情有獨鍾,會對其進行硬體加速,所以我們會發現,同樣一張背景圖,png雖然體積比jpg大但是載入速度卻要快一些。

  終上所述,對於App包中的圖片,我們都使用png格式的,而對於要從網上載入的圖片,考慮到流量以及下載速度,則使用jpg格式的,因為它有較高的壓縮率,體積很小。

  但是對於背景圖、引導頁,這種大尺寸的圖片,我們還是傾向於使用jpg格式,雖然載入慢一些,但是體積小,減少了包的體積。我看過的App基本都是這麼做的。

  對於Splash廣告圖,就是那個每次開啟App一閃而過的廣告,由於我們隔三岔五就要從線上下載新的廣告圖並展示在Spalsh頁面上,所以這裡使用jpg格式的圖片。

  對於iOS,蘋果規定啟動頁(Launch image)必須是png圖片,否則稽核時就會被拒。

  Google後來釋出了一種新的圖片格式,WebP,它的壓縮率比jpg更好,已經慢慢普及。Android自然是支援的,iOS想要使用這種格式的圖片,需要在程式中引入WebP解碼器。

4 Splash、引導圖和背景圖

  通過對50多款App中的圖片逐個分析,我發現有3種比較典型的場景,大多數公司的解決方案是雷同的:

  1. Splash預設廣告是體積最大的,而且對應不同機型,要做多套,根據我的經驗,每張圖控制在300-500k左右就可以了。解析度再高,對於手機而言,看不出效果。

  2. 引導圖,設計師每次都會給幾張高解析度的圖片,然後程式設計師不加思索直接放到App中,體積自然就變大了。其實,仔細觀察,你會發現,為了保持風格統一,這些圖片的背景都是一樣的。所以我們完全可以這樣做,比如說背景上有一隻小兔子:

  • 把背景與小兔子拆分成2張圖片。如果另一個引導圖的背景上有一隻小鴨子,那麼就只需要這張小鴨子的圖片了,背景圖可以複用。
  • 根據解析度,動態放置小兔子的位置,動態拉伸背景圖,使之鋪滿整個螢幕。

  3. 對於背景圖,為了達到一種視覺效果,這張圖片經常被新增虛化等效果,既然如此,沒有必要做得太清晰,應該控制在50k左右,看到很多App中類似的背景圖都在1M左右,實在沒有必要。背景圖一般使用jpg檔案。

5 iOS的1倍圖、2倍圖和3倍圖

  iOS不使用畫素作為單位,而是使用點這個單位,對於iPhone4及之後,1點等於2個畫素;而對於iPhone3GS及之前,1點等於1個畫素。這樣就保證了之前在iPhone3GS上執行的App,不用修改也能在iPhone4上執行。[3]

  但是原先適用於iPhone3GS的圖片,比如說a.png的尺寸是30 x 40畫素,在iPhone4中看起來就模糊了。於是我們必須為a.png再準備一張60 x 80畫素的圖片,命名為[email protected],也放到App專案中,這樣App在執行時會根據螢幕是否為iPhone3GS來選擇相應的圖片。iPhone3GS會選擇a.png,iPhone4會選擇[email protected]。對於iPhone4而言,如果沒有這張2倍圖,則選擇a.png,所以就模糊了。

  iPhone4S、iPhone5、iPhone5c、iPhone5s、iPhone6,它們都使用[email protected]這張2倍圖。

  直到iPhone6 Plus,才需要提供[email protected]的圖片。如果沒有這張3倍圖呢,它會選擇1倍圖或2倍圖,我嘗試過只有2倍圖的情況,在iPhone6 Plus上確實是模糊的效果。

  那麼問題就來了,我們需要為每張圖都提供1倍圖、2倍圖和3倍圖這3張圖片嗎?

  我看到一款國際版的App是這麼處理圖片的。它在提供了多國語言文字的同時,還為每張圖片生成了1倍圖、2倍圖和3倍圖。這就導致了這款App的體積非常大。看上去有點“寧可錯殺一千,不可放走一個”的感覺,但只要反過來想,圖片一張也不缺,永遠不會模糊。

  我檢視過很多App的圖片,發現1倍圖鋪天蓋地,但並不是每張1倍圖都有相應的2倍圖和3倍圖,或者是隻有相應的2倍圖而沒有3倍圖,當然,也有隻存在2倍圖和3倍圖而找不到1倍圖的情況。圖片管理五花八門,亂七八糟。

  但是在中國,可不是這樣哦。我看過友盟給出的資料報告,中國iPhone3GS使用者不足0.1%。於是,我有一個大膽的設想,就是把iOS App的包中所有的1倍圖都幹掉,為每張圖生成2倍圖和3倍圖。

  很多公司都有根據1倍圖批量生成2倍圖和3倍圖的工具,我也曾用C#寫過一個。但是我發現有問題,並不是每張圖片轉換後都清晰,向量圖可以拉伸,但是拉伸點陣圖就會失真。當我反過來根據3倍圖批量生成1倍圖和2倍圖時,卻發現點陣圖可以壓縮,而向量圖壓縮後會失真。於是一種好的解決方案是,先把所有圖片按照點陣圖和向量圖進行分類,屬於向量圖的,要提供1倍圖,然後批量轉換為2倍圖和3倍圖;而屬於點陣圖的,則是提供3倍圖,然後批量轉換為1倍圖和2倍圖。

  本文給出的解決方案,並不能有效減小iOS包的體積,說不定反而會增大包的大小,但是卻能系統的對圖片進行管理,從而確保每張圖片都是清晰的。

6 在iOS中進行圖片拉伸和旋轉

  在Android技術領域,流行.9圖這個概念,從而極大的節省了圖片的體積。iOS其實也可以這麼幹,使用iOS的圖片拉伸的語法,可以把一張.9圖鋪滿一個區域,比如說按鈕,如下所示:

(UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets

  其中capInsets這個引數是一個UIEdgeInsets型別的結構體,被capInsets覆蓋到的區域將會保持不變,而未覆蓋到的部分將會被用來平鋪。

  以上這個方法只適用於iOS0及以上版本,0以下版本有另外的解決方案,但是目前國內的App都只支援0以上版本了,所以這裡我就不提及了。

  對於箭頭,更沒必要準備上下左右4張圖片,準備一張圖片就夠了,使用的時候在方向上進行旋轉即可。

7 使用XML配置動畫

  動畫主要體現在引導圖中以及載入進度條上。

  對於做應用類App的開發人員,他們做動畫不是很在行,所以他們會要求設計師提供gif格式的動畫,或者二十多張圖片進行輪播,以達到gif動畫的效果,殊不知,在程式設計上簡單了,但是App的體積卻相應變大了。

  比較簡單的解決方案是,減少動畫中的關鍵幀,來降低動畫的大小。

  稍微正規一點,還是要使用原生的Android或iOS原生程式碼來實現。任何複雜的動畫,都是由四種簡單的動畫組成的,分別是:移動、旋轉、縮放、漸變。在Android中,是使用XML來配置的,上述這四種簡單動畫都有對應的XML語法,可以很快拼湊出一個複雜的動畫;而對於iOS,只好使用編碼方式了。

  我們為什麼不仿照Android的XML動畫實現技術,為iOS也量身定製一套XML的動畫標籤呢?從而不用寫任何objective-C程式碼,配置幾行XML就展現一個動畫。

  我見過一家App就是使用這個思想在plist中配置屬性來做iOS動畫的,如圖9-4所示,就是一個平移的動畫:

  clip_image004

  圖9-4 配置檔案中的平移動畫

  基於這個配置,還需要有一個動畫引擎,來解析這個配置檔案,將其翻譯成objective-C原生語言。在設計模式中,我們稱之為直譯器模式。

  不單如此,我還需要有個測試頁面,通過在這個頁面中修改動畫的屬性,然後點選按鈕能立刻看到改動後的效果,而不需要重新執行App程式。點個按鈕就能執行輸入框中的XML指令碼。

  使用上述的若干方法,我們可以把1個500KB左右的gif檔案,減小到50KB的幾張圖片,並且極大地節省了而開發成本。

8 iOS使用storyboard還是xib?

  抱歉,我始終不喜歡storyboard,但是存在即合理。我曾經認為storyboard比xib大,是導致iOS安裝包體積變大的一個原因,於是我做了一件探索性的工作,就是把storyboard中的頁面拆分為若干個xib檔案,然後重新打包,但是結果卻是前後大小一致。

  結論是,是否使用storyboard,對ipa包大小沒有影響。

9 字型檔案的學問

  我在某個ipa包中發現了ttf格式的字型檔案。起初還以為是他們的App使用了某種特定字型,但開啟這個ttf檔案後才發現,這裡面存放的居然是圖片,如圖9-5所示:

  clip_image006

  圖9-5 字型檔案中的icon圖片

  每個icon對應一個十六進位制的數字,比如說第一個是\Ue600,這個值是唯一的。

  觀察這個字型檔案,我們看到所有的icon具有以下共性:

  • 這些icon都是單色的,可以在App中的頁面裡設定這些icon為其他顏色,但也必須是單色。
  • 這些icon可大可小,因為它們是一種“字型”,字型是向量圖,所以拉伸不會失真。
  • 這個ttf檔案體積很小,比做成單獨的png圖片要小。

  有人立刻就會聯想到iOS的1倍圖、2倍圖和3倍圖,每次都要準備3張圖片,分別適用於不同的手機型號。如果做成一個字型,就可以減少體積,再也不用設計@2x和@3x兩套圖了——這種方案僅限於單色圖片。

  我們一般到下述網站來把單色icon轉換成字型檔案:https://icomoon.io。或者使用FontLab這樣的工具自己來製作。

  接下來我們來看如何在App中推廣這門技術。

  1)Android

  首先把這個字型檔案放到assets目錄下,如圖9-6所示:

  clip_image008

  圖9-6 assets目錄下的字型檔案

  接下來,我們將icon和十六進位制編碼的對映關係儲存在drawable資原始檔中:

<string name="font_icon_1_normal">&#xe606;</string>
<string name="font_icon_1_pressed">&#xe607;</string>

  這樣就可以使用R.id.font_icon_1_normal這樣的語法來取出這個圖片了。

TextView textView1 = (TextView) findViewById(R.id.textView1);
Typeface font = Typeface.createFromAsset(getAssets(), "icomoon.ttf");
textView1.setTypeface(font);
textView1.setTextSize(12);
textView1.setText(getResources().getString(R.string.font_icon_1_normal));

  也可以將其設計為一個Drawable物件,然後設定給ImageView這樣的控制元件。

  2)對於iOS,實現思路差不多。

  首先我們要把icmoon.ttf檔案新增到專案中,如圖9-7所示:

  clip_image014

  圖9-7 UseIconInTTF中的icomoon.ttf檔案

  在Supporting Files目錄下的UserIconInTTF-Info.plist檔案中,增加一個配置,型別指定為Fonts provided by application,在其中新增對icomoon.ttf字型檔案的宣告,如圖9-8所示:

  clip_image016

  圖9-8 在UseIconInTTF-Info.plist配置icomoon.ttf

  與Android類似,為了不直接使用\ue605這樣的十六機制編碼數字,我們將icon和十六進位制編碼的對映關係定義為一個巨集TTFConstants:  

#define font_icon_1_normal "\ue605"
#define font_icon_1_pressed "\ue606"

  接下來只要兩行程式碼就能顯示這個字型檔案中的圖片:

[self.label1 setFont:[UIFont fontWithName:@"icomoon" size:12]];
[self.label1 setText:
[NSString stringWithUTF8String: font_icon_1_normal]];
10 表情圖片打包下載

  對於表情圖片。很多App中集成了聊天功能,有了聊天,自然就要提供各種表情圖片,有靜態圖png,也有動畫gif,雖然每個都不大,但是數量多啊,都打到包裡面一起釋出,會直接導致包變大。

  考慮到實際的場景,使用者不會一開啟App就使用聊天功能,所以我們可以把這些表情圖片打包成一個Zip包,在啟動App的時候,在一個新的執行緒中非同步下載這個Zip包然後解壓到本地。這樣以後聊天的時候就可以使用本地的圖片了。對此,我們要做好版本增量升級功能,以確保有新表情圖片的時候也能下載到本地後使用。

11 清除未使用圖片

  對於Android而言,Eclipse可以自動檢查出哪些圖片沒有用到。

  對於iOS而言,則需要寫個小程式,逐一檢查哪些圖片沒有使用到,注意,對於[email protected][email protected]的處理,要先將@2x和@3x過濾掉。

  無論是Android還是iOS,即使發現到冗餘圖片,也不能直接刪除,因為我們的程式經常會在程式碼中動態決定要顯示哪些圖片,我們只能檢查這些圖片在版本庫的修改歷史,來決定這些圖片是否真的不需要了。

12 Proguard不只是用來混淆的

  一提起Android中的Proguard,我們首先想到的是程式碼混淆,那是因為我們要經常去修改proguard.cfg檔案,去keep那些不需要被混淆的類和方法。

  其實,Proguard還能瘦身apk,在打包時它會幫忙檢查那些不使用的類和方法,將其移除。最有效果的就是那些第三方SDK了,比如說aSmack這個用於xmpp的SDK有幾萬個方法,但其實我們只使用其中很小的一部分。Proguard會幫助我們把不使用的部分移除,從而極大的減小了apk的體積。

13 在iOS中使用pdf格式的圖片

  在研究各家App的過程中,我發現某款App的ipa檔案中有幾張pdf格式的圖片。

  在研究中還發現,有幾款App的ipa包中的每張圖片都做成imageset的形式,每個imageset目錄中都同時存在這張圖片的1倍圖、2倍圖和3倍圖,如圖9-9所示:

  clip_image022

  圖9-9 cancelSelectedListBtn.imageset目錄下的3張圖片

  上述這兩件看似無關的事情,咋一看毫無關聯,其實是使用了iOS的一個新技術。讓我們從這些蛛絲馬跡中探賾索隱。

  就是這幾張pdf圖片,我研究了半天,請設計師同學做成同樣的png圖片,體積相差不大,所以和png相比毫無優勢。由於這個App的ipa包中有幾百張圖片,其中只有這3張圖片是pdf格式的,所以我懷疑,這只是他們的新技術嘗試。

  再觀察imageset目錄下的那3張圖片,我發現每張圖片都是這樣的。這不由使我意識到,一定是用了什麼工具,一次性生成的這些圖片。

  搜尋關鍵字ios+pdf,直到找到《Using Vector Images in Xcode 6》這篇文章[4],才發現這是iOS8才出現的一種新技術,只能在XCode6上使用。

  在這裡簡單介紹一下這門技術,先繪製一張pdf向量圖,然後XCode6在編譯的時候,會生成3張pdf格式的圖片,分別是1倍圖、2倍圖、3倍圖。這樣就避免了圖片不全導致的模糊,也避免了每次都要設計師準備3套圖的麻煩。

  但是,我們為什麼要在使用者的iPhone上裝一些永遠用不到的圖片呢?蘋果煞費苦心的搞出來這樣一門技術,仍然沒有解決App體積日益膨脹的現實,而且這門技術只會讓App的體積變得更龐大——而這才是使用者的痛點所在。如果是我來設計下一版iOS,我會讓App中只包括pdf向量圖,只有在使用者下載完App開始安裝的時候,才會根據使用者的機型,把pdf轉換為相應的圖片,比如說iPhone 6+上App生成的圖片就是3倍圖。

  蘋果公司在iOS9中推出了App瘦身功能,據說能大幅減少要下載的App包的體積。具體效果如何,我們拭目以待。

14 iOS的包永遠比Android包體積大嗎?

  我比較了100多款App後發現,同一款App的iOS和Android版本,iOS的ipa包的一定比Android的apk包在體積上大很多。

  但總是有特立獨行的App,比如說某款著名視訊播放軟體,Android版本23.2M,而iOS版本才20.5M。我起初以為這個App的Android版本做的有問題,於是仔細研究了這個Android包裡的內容,我就發現這家公司Android技術做的很精緻,之所以比iOS版本體積大,是因為Android版本為幾十種解析度都適配了不同的圖片和佈局,以確保使用者體驗在任何解析度下都是一致的。

  如圖9-10所示,居然有12種layout佈局:

  clip_image024

  圖9-10 Android專案中的Layout資料夾

  drawable資料夾就更多了,高達28個,限於篇幅,這裡就不貼圖了。

  以上只是特例,而大多數App並沒有做的那麼細緻,比如說:

  1)首先是不支援那麼多解析度。這是由當前App的開發現狀導致的。一方面是產品經理和設計師在人力的不足,另一方面則因為設計師偏愛iPhone,一般只會給出iPhone版本的設計稿,然後讓Android開發人員根據iPhone的設計稿去適配。於是Android開發人員只好去做UI自適應,使用.9圖拉伸技術,實在搞不定了,才去找設計師重新給畫一張。所以我們會看到iPhone的App大都很精緻,相應的Android版本都很粗糙,這是因為Android App的UI很多都是開發人員憑著自己的審美觀去二次加工的。

  2)其次,你會發現,不同drawable目錄下放置著不同內容的圖片。用開發人員的畫講,好找。比如說drawable目錄下放各種Selector檔案,drawable–hdpi目錄下放美食類圖片,drawable-large目錄下放門票圖片。所以說,目錄雖多,但其實只有一套圖。殊不知,這樣反而降低了App執行的速度,因為它在相應解析度的drawable目錄下找不到某張圖片時,就會逐個遍歷每個drawable目錄下的圖片,直至找到該圖片的位置。

15 從程式碼層面減少iOS包的體積

  對於iOS而言,在ipa包中會有一個.a格式的二進位制檔案,這是程式碼編譯後生成的檔案,往往佔據了整個ipa包的50%到80%的體積。蘋果曾要求所有的App都支援64位,於是在此基礎上,ipa包的體積又擴大了將近一倍,主要是那個.a檔案編譯後變大了。

  我們要想辦法減少這個.a檔案的大小,其實就是要減少專案中的冗餘程式碼。經過不斷地摸索和嘗試,我發現這些冗餘程式碼分為3部分:

  1)已經不使用的類。為此,我們需要寫一個Python指令碼,逐個檢查哪些類不再使用了。檢查的過程中我發現,某個類即使不使用了,但是在其他類中仍然保持對它的引用,所以我們要排除掉這種特殊情況,不讓它對我們的檢查工作造成影響。

  還存在這麼一種情況,在A類中使用了B。A類不再使用了,第一遍執行Python指令碼找出來A類,將其刪除了。這時B類就孤零零的放在那裡,也不再使用了,所以我們有必要再次執行Python指令碼,將B找出來。以此類推,不停地執行這個Python指令碼,直到再也找不到不再使用的類為止。

  2)已經不再使用的方法。這個找起來有些費勁,因為Objective-C獨特的方法簽名形式(方法簽名由三部分組成,包括方法名稱、引數和返回型別)。

仍然是寫一個Python指令碼,逐個遍歷每個類中的方法,然後到專案中查詢是否使用到了。

  在執行過程中,遇到這麼一種情況,A類和B類都有這個loveBaobao這個方法,方法簽名也完全相同。這時Python是區分不出來到底是使用了哪個類的loveBaobao方法的。我們也只能將其彙總起來,然後用手動檢查。

  此外,有很多方法是系統自帶的,比如說UITableView的那6個方法,只要是使用了UITableView的頁面,都有這6個方法。我們在執行Python指令碼的時候,不應該統計這樣的方法。所以需要做一個白名單,事先把這些方法填進去。

  3)程式碼相似度問題。初級程式設計師在寫程式碼時,喜歡把一段程式碼從A類貼上到B類中,然後修改其中的幾個變數名稱,這個功能就算做完了。於是兩段相似度極高的程式碼就產生了。

  稍微懂得些面向物件思想的人,都知道這時候需要把這樣的程式碼抽象出來,比如說在Utils類中新建一個方法,然後要用到這段邏輯的人呼叫Utils類的這個方法即可。

  但並不是所有的程式設計師都有這樣的境界,即使是有幾年經驗的人,也會因為急著下班二人世界或者給孩子換尿布而採用複製貼上大法敷衍了事。久而久之,冗餘程式碼就多了,包的體積自然就大了。為此,我們需要有一個檢查程式碼相似度的工具。在iOS領域,我推薦Simian這個工具。有興趣的讀者可以嘗試一下,對你們的專案使用一下這個工具,看能找出來多少相似的程式碼來。

[1] 關於Android增量更新技術,請參見http://blog.csdn.net/hmg25/article/details/8100896

[3] 詳細內容請參見知乎上的這篇文章:http://www.zhihu.com/question/25421514/answer/31623909

[4] 文章參見http://martiancraft.com/blog/2014/09/vector-images-xcode6/

相關推薦

App技術分析 3減小安裝體積

1 從幾件小事說起   春節在家幫姐姐的iPhone手機安裝市面上形形色色的App,忘記她是使用4G流量包月了,於是在下載了10個App後,不但耗盡了流量,還按照0.3元/兆的價格扣了七八十元流量費用。後來我檢查了這幾個App的體積,發現每個App體積都是40-50M的樣子

App技術分析 8模組化拆分

1 iOS資源拆分與模組化  對於iOS,很多App已經注意到圖片會散落在各個地方,於是會把圖片、配置檔案、xib按照模組進行歸類,放到各自的bundle包中。做得最好的,是一家電商App,會在App包中的一級目錄下面,看不到任何圖片,而只有若干bundle,如圖9-18所示

App技術分析 7逼出來的奇思妙想

1 一切皆可配置1.1 使用XML配置首頁,防止因載入不到資料而沒有入口  在很多電商類App中,我們會看到有一個配置檔案或者JSON檔案,裡面存放著首頁展示所需要的所有資料,包括圖片、文字等等,點選後能進入各個品類這些二級頁面,如圖9-15所示,我們可以看到,這個首頁由3個

App研發錄 架構設計 Crash分析App技術分析

第1章原始碼:  1.1 重新規劃Android專案結構  1.1.zip  1.2 為Activity定義新的生命週期 1.2.zip  1.3 統一事件程式設計模型      1.3.zip  1.5 Adapter模板   1.5.zip  1.6 型別安全轉換函式   1.6.zip  第2章原

Spring Cloud技術分析3- spring cloud sleuth

地址:http://tech.lede.com/1. 目的提供鏈路追蹤。通過sleuth可以很清楚的看出一個請求都經過了哪些服務。可以很方便的理清服務間的呼叫關係。視覺化錯誤。對於程式未捕捉的異常,可以在zipkin介面上看到。分析耗時。通過sleuth可以很方便的看出每個取

App 研發錄、架構設計、Crash分析技術分析------讀書筆記(第二章)

網路底層框架設計 1、不要自己定義網路請求框架,網路層不要使用AsyncTask 2、在網路返回資料Response的應該有一個規範的格式 { "isError":true, "errorType":1, "errorMessa

【雲安全與同態加密_調研分析3】國內雲安全組織及標準——By Me

pac 調研 通信 bsp group 移動 網絡通信 body 中興 ◆3. 國內雲安全組織及標準◆ ◆雲安全標準機構(主要的)◆ ◆標準機構介紹◆ ◆相關標準制定◆ ◆建立的相關模型參考◆ ◆備註(其他參考信息)◆ ★中國通信標準化協會(CCSA

redis源碼分析3-- 基本數據結構雙鏈表list

direction 函數指針 all eas 源碼 計數 type ima blog 一、雙鏈表結構 redis中實現的雙鏈表結構體如下: 1 typedef struct list { 2 listNode *head; # 鏈表頭 3 listNode

redis源碼分析3-- 基本數據結構字典dict

下一個 edi code int current tty 大小 .com 個數 一、字典結構 Redis中字典采用hash表結構,如下: typedef struct dictht { dictEntry **table; // hash表數組 uns

區塊鏈技術系列3- Fabric基礎架構原理

多看 技術分享 發的 size 開源項目 初始 排序。 創建 生成 前言 對於區塊鏈方面多技術,我還是建議大家多看英文文檔,多利用Google來搜索技術文章。 怎麽搭建自己專屬V-P-N來訪問Google,請看我之前發的文章: 新人如何快速搭建自己的個人網站以及自己專屬

Arm虛擬化:效能和構架分析3

                     構架的改進 為了在真實應用workload上得到更低的VM到hypervisor延遲,我們需要對arm硬體虛擬化支援做些改進。根據我們的設計,實

Mybatis原始碼分析3—— 從Mybatis的視角去看Bean的初始化流程

不涉及Spring完整的啟動流程,僅僅從Mybatis的視角去分析幾個關鍵的方法,找到Mybatis是如何通過這幾個擴充套件點植入進去的,反過來看Spring是如何設計,埋下這些伏筆,實現其可擴充套件性。 springContext-mybatis.xml的配置: <!--

PackageManagerService 原始碼分析 3 ApplicationInfo 相關

PackageParser.Package.ApplicationInfo  類 Application 是PackageParser.Package 的一個成員   一   . 呼叫情況: 1.PackageParser.parseBaseApk

2019年移動社交APP前瞻性分析

社交的本質是什麼?筆者認為社交的本質是一個使用者社交資產成長的遊戲。在這個遊戲裡,使用者根據自身社交資產的成長曲線,來挑戰對應難度的社交目標。 對於2019年社交賽道,我們可以從兩個方向來預測,每個方向我們會結合今年年底出現的新產品來談。 預測一:賽道中會出現數款現象級的輕資產社交產品 重資產與輕資產是

LoadRunner測試結果分析3

前面分析的Web Resource(網路資源)的測試情況,其主要關注的是伺服器效能,而系統本身和環境都有可能存在問題,頁面診斷(Web Page Diagnostics)主要就是關注這方面的問題。頁面診斷可以很好地定位環境問題,如客戶端問題、網路問題等,也可以很好的分析系統本身的問題,如網頁問題。

3---Django rest framework原始碼分析3----節流

Django rest framework原始碼分析(3)----節流 目錄 新增節流 自定義節流的方法  限制60s

播放器技術分享3:音畫同步

搞音視訊開發好些年,分享過許多部落格文章,比如:前幾年釋出的《FFmpeg Tips》系列,《Android 音訊開發》系列,《直播疑難雜症排查》系列等等。最近想把多年來開發和優化播放器的經驗也分享出來,希望能幫助到音視訊領域的初學者。第一期文章要推出的內容主要涉及到播放器比較核心的幾個技術點,大概的目錄

Netflix Eureka原始碼分析3——listenerEurekaBootStrap監聽類分析

 web.xml中的listener: <listener> <listener-class>com.netflix.eureka.EurekaBootStrap</listener-class> </listener>

Android鎖屏勒索病毒分析3刷贊

1.樣本概況 1.1 基本資訊 樣本名稱: 刷贊. 所屬家族: 鎖屏勒索病毒(a.rogue.SimpleLocker.a) MD5值: 7626090b69cd1e2e5671a022712808eb 包名: com.binge.mohe 入口: Mai

JDK原始碼分析3HashSet

HashSet HashSet簡介 HashSet特點 非執行緒安全 允許null值 新增值得時候會先獲取物件的hashCode方法,如果hashCode 方法返回的值一致,則再呼叫equals方法判斷是否一致,如果不一致才add元素。 注意: 對於HashS