整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          企業網頁推廣出現移動端兼容問題怎么解決?分享幾個實用的css代碼

          業網頁推廣時出現網頁兼容問題,不僅在pc端開發中會碰到,而且在APP開發當中也會經常碰到。

          1、禁止圖片點擊放大

          部分安卓手機點擊圖片會放大,如需要禁止放大,只需要設置css屬性,這樣會讓img標簽的點擊事件失效,如果想要給圖片添加點擊事件就要給上面再寫一層。

          方案:img{ pointer-events:none; }

          2、禁止iOS設別長串數字為電話

          方案:<meta name="format-detection" content="telephone=no" />

          3、禁止賦值、選中文本

          方案:設置CSS屬性,-webkit-user-select:none

          4、一些情況下對非可點擊元素如(label,span)監聽點擊事件,不會在iOS下觸發

          方案:css屬性增加 cursor:pointer

          5、上下拉動滾動條時卡頓、慢

          方案:body{ -webkit-overflow-scrolling:touch;overflow-scrolling:touch; }

          6、安卓不會自動播放視頻

          安卓手機的autoplay沒有生效,需要手動觸發一下

          方案:window.addEventListener('touchstart',()=>{ audio.play(); },false)

          7、半透明的遮罩層改為全透明

          在iOS上,當點擊一個鏈接或者通過js綁定了點擊事件的元素時,會出現一個半透明的背景,當手指離開屏幕,灰色背景消失,出現“閃屏”

          方案:html,body{ -webkit-tap-highlight-color:rgba(0,0,0,0); }

          8、ios系統全屏狀態下瀏覽器上下滾動時會出現底色問題

          移動端項目要求是全屏滾動,用的是 fullpage,上下滾動時安卓正常,蘋果手機瀏覽器上下滾動時會出現底色問題

          方案:document.body.addEventListener('touchmove',function(e) { e.preventDefault();}, {passive:false})。

          個功能也是很常見了,一般都是為了方便用戶操作,比如復制訂單編號。不廢話,下面就來看看具體是怎么操作的。

          1.復制內容要剪切板

          tv_order_copy.setOnClickListener {
              //獲取剪切板管理器
              val cm: ClipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
              //設置內容到剪切板
              cm.primaryClip = ClipData.newPlainText(null, item.orderId)
              ToastUtils.show(context, "已復制")
          }
          


          非常簡單,首先獲取剪切板管理器,然后設置內容即可可以設置的內容有3種類型:

          • newPlainText
          • newHtmlText
          • newIntent

          2.清除剪切板

          tv_order_clear.setOnClickListener {
              val cm: ClipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                  //要api28以上
                  cm.clearPrimaryClip()
              } else {
                  cm.primaryClip = ClipData.newPlainText(null, null)
              }
          }
          


          在api等級28以上,直接調用clearPrimaryClip()即可,以下,重新設置為空即可。

          3.獲取剪切板內容

          iv_order_get.setOnClickListener {
              val cm: ClipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
              if (cm.hasPrimaryClip() && cm.primaryClip != null) {
                  //cm.primaryClip.itemCount
                  val text = cm.primaryClip.getItemAt(0).text
                  ToastUtils.show(context, text.toString())
              }
          }
          


          在有內容的情況下,這里的代碼是取的第一個,即getItemAt(0).text,如果有多個的情況下,且有取多個的需求,這里的下標取值就要根據cm.primaryClip.itemCount來動態設置了。

          代在進步,第三套少兒廣播體操!不好意思,搞錯頻道了,重來!時代在進步,Android的版本也是快速的進行著迭代著,從我們以前最常見的Android 4.4一直發展到了今天的Android 11版本(即Android K到Android R),Android版本的快速迭代對于消費者來說是一件普天同慶的大好事情,但是對于我們開發者來說各種適配各種改造有時候吃翔的心情都有了。而對于Android版本的適配和各種改造的第一步就是從編譯Android源碼開始,可是不幸的是隨著Android版本的迭代連編譯Android源碼的相關流程都發生了翻天覆地的變化,正所謂工欲利其事必先利器,所以我們今天的這篇博客將帶領讀者一起來到Android各個版本的源碼編譯發展和編譯具體操作步驟!

          這里我們需要注意一下Android各個版本的對應關系如下:

          Android 5.x (Lollipop)簡稱Android L版本Android 6.0 (MarshMallow) 簡稱Android M版本Android 7.x (Nougat)簡稱Android N版本Android 8.x (Oreo)簡稱Android O版本Android 9.0 (Pie)簡稱Android P版本Android 10.0 (Q)簡稱Android Q版本Android 11.0 (R)簡稱Android R版本

          并且這里還有一點需要特別注意,本文演示的Android R版本是以高通平臺為基準進行的。



          一.Android編譯環境的構建以及常見命令

          ??俗話說天時地利人和缺一不可,而這其中的地利翻譯過來說的就是環境因素了,人的成長離不開環境因素,而我們的Android編譯也離不開編譯環境的構建!雖然我們本篇博客的主題是Android源碼編譯指南,但是我們還是有必要抽出一個章節來簡單說明下Android編譯環境的構建和初始化過程,以及初始化完畢后常見的命令。


          1.1 Android編譯環境的構建

          本章節重點偏向的是Android編譯環境的構建,而不是編譯環境構建的原理分析(如果是原理分析,那內容就多了,關于Android編譯墻裂推薦一篇博客來自IBM社區理解 Android Build 系統,你值得擁有!)。

          雖然Android的版本一直在迭代著,但是Android編譯環境的構建步驟還是比較良心的依然沒有多大的變化(注意這里的措辭,只是步驟),對于有過Android源碼開發經驗的讀者來說是再為熟悉不過的了,通常是如下二部曲:

          $ source build/envsetup.sh
          $ lunch aosp-eng
          12

          雖然各位對上述的命令應該已經爛熟于心了,但是這里我還是簡單說明一下:

          • 第一行命令”source build/envsetup.sh”引入了build/envsetup.sh 腳本。該腳本的作用是初始化編譯環境,并引入一些輔助的Shell函數,這其中就包括第二步使用 lunch 函數
          • 第二行命令”lunch aosp-eng”是調用 lunch 函數,并指定參數為”aosp-eng”。lunch 函數的參數用來指定此次編譯的目標設備以及編譯類型。在這里,這兩個值分別是”aosp”和”eng”。”aosp”是 Android 源碼中已經定義好的一種產品,是為模擬器而設置的。而編譯類型會影響最終系統中包含的模塊。如果在調用lunch函數的時候沒有指定參數,那么該函數將輸出列表以供選擇,列表內容不同Android版本,不同廠家的基線源碼會有所不同,如下:


          這里補充一點對Android的源碼編譯類型簡單說明一下,它可以分為如下三種功能,每種類型的特點如下:



          1.2 Android編譯各種常見命令

          在編譯環境初始化完成后,我們就可以使用各種各種編譯環境提供的指令和make編譯命令族來開啟Android的構建之旅了,這里我簡單的總結了下,我們在Android編譯中可能會用到的編譯環境提供的指令和make編譯命令族,如下:

          1.2.1 常見的Android命令指令

          指令說明??croot ??切到Android源碼樹的根目錄(當你深入Android源碼樹的子目錄,想回到根目錄的時候此命令就非常實用了)m相當于在源碼樹的根目錄執行make,并且該命令不一定要在根目錄下執行mm編譯當前目錄路徑下的所有模塊(包括include進來的,但是不包括存在依賴關系模塊)mma編譯當前目錄路徑下的所有模塊(包括include進來的,且包括存在依賴關系模塊)mmm[module_path]編譯指定目錄路徑下的所有模塊(包括include進來的,但是不包括存在存在依賴關系模塊)mmma[module_path]編譯指定目錄路徑下的所有模塊(包括include進來的,包括存在存在依賴關系模塊)cgrep對C/C++文件執行grep(即grep的時候只搜尋C/C++文件類型,注意這里也包括.h文件類型)jgrep對Java文件執行grep(即grep的時候只搜尋Java文件類型)resgrep在所有res/.xml文件上執行 grep即grep的時候只搜尋res/.xml文件類型)printconfig顯示當前Android編譯的相關配置信息add_lunch_combo在lunch命令的的菜單中添加一個條目

          這里我們對上述表格中的"不包括存在依賴關系的模塊"簡單解釋一下:
          1.依賴關系模塊這個要怎么說呢,這里我們舉個例子!譬如模塊A的編譯需要依賴模塊B,此時的B是一個so庫。
          2.假如我們通過mm或者mmm編譯模塊A的時候,此時B模塊還沒有編譯那么此時就會報錯
          3.假如我們使用的是mma或者mmma編譯模塊A,假如依賴的模塊B還沒有編譯,那么會先將模塊B編譯OK,然后編譯模塊A(當然這里只是舉栗子,可能A還依賴C,D同理也會先編譯)

          1.2.2 make編譯命令族

          Android的Build編譯系統處理常見的make單命令之外,還提供了其它的一系列make命令族,這里我們簡單過下:

          指令說明make update-api更新API文件,在framework API改動之后,需要首先執行該命令來更新API,公開的API記錄在frameworks/base/api目錄下makeAndroid默認系統編譯指令,會編譯出整個系統的所有鏡像(其實質最終執行的是make droid)make droid同上make sdk編譯出Android的SDK開發套件make clean-sdk清理SDK的編譯產物make dist執行整個編譯,并將 MAKECMDGOALS變量定義的輸出文件拷貝到 /out/dist目錄下,
          這個命令在實際中用的比較少
          make all編譯所有內容,不管當前產品的定義中是否會包含,官方解釋如下:
          builds everything make droid does,plus everything whose LOCAL_MODULE_TAGS do not include the “droid” tag. The build server runs this to make sure that everything that is in the tree and has an Android.mk builds.
          make help幫助信息命令,顯示當前Android版本主要支持的make命令make snod從已經編譯出的包快速構建系統鏡像(譬如你重新單獨編譯了某個模塊,然后想快速進行打包到system.img,可以使用此命令加快速度)make clean-$(LOCAL_MODULE)Let you selectively clean one target. For example, you can type make clean-libutils and t will delete libutils.so and all of the intermediate files.
          即清理掉一個指定模塊的編譯結果和中間產物
          make clean-$(LOCAL_PACKAGE_NAME)Let you selectively clean one target. For example, you can type
          make clean-Home and it will clean just the Home app…
          即清理掉一個指定模塊的編譯結果和中間產物
          make cleandeletes all of the output and intermediate files for this configuration. This is the same as rm -rf out/<configuration>/
          通常刪除的是整個Android源碼工程的out/*目錄
          make clobberdeletes all of the output and intermediate files for all configurations. This is the same as rm -rf out/.
          這個命令在實際中,應用得比較少
          make datacleandeletes contents of the data directory inside the current combo
          directory. This is especially useful on the simulator and emulator, where the persistent data remains present between builds.
          這個命令在實際中應用得也比價少
          make installclean當我們在執行切換編譯目標時可以執行make installclean,用以清除之前編譯生成的文件,但是又不會將整個out目錄清空,這樣可以加快編譯目標的構建速度make LOCAL_MODULE編譯一個指定的模塊,LOCAL_MODULE 為模塊的名稱,這種編譯方法通常運用在整個Android工程沒有構建,但是想快速編譯一個模塊時可以使用,可以加快單個模塊構建速度make targetswill print a list of all of the LOCAL_MODULE names you can make.make libandroid_runtime編譯所有JNI framework內容。make framework編譯所有Javaframework內容(做Android framework開發的小伙們對這條命令應該是再熟悉不過的了)。make services編譯系統服務和相關內容make bootimage編譯生成boot.imgmake recoveryimage編譯生成recovey.imgmake cacheimage編譯生成cache.imgmake systemimage編譯生成system.imgmake vendorimage編譯生成vendor.imgmake superimage編譯生成superi.img

          對上述的make命令有幾點需要注意:
          1.可能在不同的Android版本有不同表現,且有的可能已經不支持了
          2.讀者最好對于每個make編譯命令,自行使用一番,然后慢慢品嘗



          二.Android編譯的發展史簡介

          ??有過一定Android開發經驗的讀者應該知道Android最初是用Android.mk配置來編譯源碼的(這里的Android.mk本質上有點類似Makefile文件)。但是隨著Android版本的迭代,源碼工程文件越來越大,包含的模塊越來越多,而以Android.mk組織的項目編譯花費的時間越來越多。面對這個嚴峻的問題,Android的媽咪谷歌終于在在Android7.0開始引入了ninja編譯系統。相對于make來說ninja在大的項目管理中速度和并行方面有突出的優勢,因此Google采用了ninja來取代之前使用的make。由于Android.mk的數量巨大且復雜,不可能把所有的Android.mk改寫成ninja的構建規則,因此Google搞了個kati工具,用于將Androd.mk轉換成ninja的構建規則文件build.ninja,再使用ninja來進行構建工作。

          ??Android編譯的發展依然沒有停止進化,果不其然Android8.0開始,Google引入了Android.bp文件來替代之前的Android.mk文件,Android.bp只是純粹的配置文件,不包括分支、循環等流程控制,本質上就是一個json配置文件。同時還引入Soong這個工具,用于將Android.bp轉換為ninja的構建規則文件build.ninja,再使用ninja來進行構建工作。但之前的模塊全部是用Android.mk來定義的,google不可能一下子把所有模塊都修改成Android.bp,只能逐步替換。無論是Android.mk還是Android.bp最后都是轉化成ninja的構建規則,再進行編譯的。

          如果你對上述的概述,還是覺得太啰嗦了,沒有關系。這里我們用更加簡單的文字來整體來概括一下Android build系統隨著Android版本相應的發展演變過程:

          • Android 7.0引入ninja和kati
          • Android 8.0使用Android.bp來替換Android.mk,引入Soong
          • Android 9.0強制使用Android.bp


          2.1 Soong、Blueprint、Kati、Ninja關系

          通過前面的章節,我們簡單介紹了Android編譯系統的發展史!讀者會發現,其中突然一下子冒出了許多的概念,這里我們先暫且不對其中涉及的概念深入了解,我們先說說上述幾個概念Soong、Blueprint、Kati、Ninja之間的關系,它們之間的關系圖如下:

          上圖是一個靜態的整體的關系圖,但是在Android源碼工程構建過程中的它們之間可以使用如下的轉換關系圖來表示:

          關系圖已經給各位看官擺出來了,那么它們之間的轉換關系是怎么來的呢,這里我們來說說:

          • 首先通過Kati將Android.mk轉換成ninja格式的文件
          • 通過androidmk將將Android.mk轉換成Android.bp,但是只針對沒有分支、循環等流程控制的Android.mk才有效,如果對于有控制流的就必須手動了具體可以想見博客Android.bp正確姿勢添加宏控制編譯指南
          • 通過Blueprint+ Soong將Android.bp轉換成ninja格式的文件

          不容易啊,這里我們對涉及到Ninja, kati, Soong, bp關系搞清楚了(各種三角戀)!那么關于它們的概念,接下來我們也得簡單介紹介紹,安排上才行!


          2.2 Kati簡介

          Kati是專為Android開發的一個基于Golang和C++的工具,主要功能是把Android中的Android.mk文件轉換成 Ninja文件。代碼路徑是build/kati,編譯后的產物是ckati。

          Kati代碼是開源的,可以把它clone下來,如果感興趣可以查看下其實現原理

          這里我們構建一個通過Android.mk配置的LOCAL_MODULE模塊,然后通過top命令就可以查看在編譯的過程中執行了ckati的命令。



          2.3 Ninja簡介

          ninja是一個編譯框架,會根據相應的ninja格式的配置文件進行編譯,但是ninja文件一般不會手動修改,而是通過將Android.bp文件轉換成ninja格文件來編譯。


          2.4 Android.bp簡介

          Android.bp的出現就是為了替換Android.mk文件。而bp跟mk文件不同,它是純粹的配置,沒有分支、循環等流程控制,不能做算數邏輯運算。如果需要控制邏輯,那么只能通過Go語言編寫。Android的媽咪谷歌為了讓開發者能更加的快速掌握Android.bp特意提供了androidmk命令(關于它的詳細介紹可以參見博客Android.bp入門指南之Android.mk轉換成Android.bp,這里就不過多的戲說了)用于Android.mk轉換成Android.bp使用,如下轉換命令:

          $ androidmk Android.mk > Android.bp
          1


          2.5 Blueprint和Soong構建編譯系統

          2,5.1 Soong簡介

          Soong類似于之前的Makefile編譯系統的核心,負責提供Android.bp語義解析,并將之轉換成Ninja文件。Soong還會編譯生成一個androidmk命令,用于將Android.mk文件轉換為Android.bp文件,不過這個轉換功能僅限于沒有分支、循環等流程控制的Android.mk才有效。

          2.5.2 Blueprint簡介

          Blueprint是生成、解析Android.bp的工具,是Soong的一部分。Soong負責Android編譯而設計的工具,而Blueprint只是解析文件格式,Soong解析內容的具體含義。Blueprint和Soong都是由Golang寫的項目,從Android 7.0,prebuilts/go/目錄下新增Golang所需的運行環境,在編譯時使用。并且因為Soong和Blueprint是Google谷歌為Android.bp特別定制的工具,所以不需要要摘出來單獨來操作。



          三.高版本P/Q/R源碼編譯

          ??通過前面的章節我們了解了Android編譯環境的構建和編譯的發展史(前面的章節都是為了后面章節服務做的整體鋪墊),那么從本章節開始就要契合本篇博客的主題了將重點分析Android O之后高階版本的編譯的不同之處了。在本篇的博客開始就有說到過是以高通版本的Android R為基線來進行分析的。所以在開始本章節的博客前,有兩個知識點需要提前介紹下,一個是Android Q以及之后的動態分區概念,另外一個就是高通Q之后引入的QSSI(或者qssi)的概念!


          3.1 Android動態分區

          動態分區是Android的用戶空間分區系統。使用此分區系統,您可以在無線下載(OTA)更新期間創建、銷毀分區或者調整分區大小。借助動態分區,供應商無需擔心各個分區(例如system、vendor和product)的大小。取而代之的是,設備分配一個super分區,其中的子分區可動態地調整大小。單個分區映像不再需要為將來的OTA預留空間。相反,super中剩余的可用空間還可用于所有動態分區(關于動態分區詳見谷歌官方Android實現動態分區)。



          3.2 什么是QSSI

          QSSI 是 Qualcomm Single System Image 的縮寫,并且高通平臺從Android Q開始支持。高通的官方文檔對此的解釋是引入QSSI的概念是為了解決Android碎片化問題,把system.img和vendor.img進一步拆分。



          并且其編譯也和Android原生編譯有差別,其差別如下:




          3.4 高版本Android非QSSI特性的整體編譯流程

          高版本Android非QSSI特性的編譯流程,依然和以前的版本Android編譯變化不大,通常是如下的步驟(這個也是讀者最為熟悉的了):

          source build/envsetup.sh 
          lunch xx-userdebug
          make
          123

          這里需要注意的的是通用版本的Android還是可以直接通過make相關的分區進行直接編譯的,譬如make superimage或者直接執行make編譯


          3.4 具有QSSI特性Android高版本整體編譯流程

          通過前面看到QSSI特性的固件編譯流程也和通用版本的有一定的區別,這里的編譯分為兩種模式,第一種Android的標準編譯模式,另外一種就是高通提供的編譯腳本。

          3.4.1 通過Android內置make命令編譯

          • 初始化編譯環境
          source build/envsetup.sh 
          1
          • 編譯 system.img
          lunch qssi-userdebug
          make target-files-package
          12
          • 編譯除system.img外的其他img
          lunch xx-userdebug
          make target-files-package
          12

          3.4.2 高通提供的build.sh腳本進行編譯

          • 編譯所有img,包括system和其它img
          source build/envsetup.sh
          lunch XX-userdebug
          ./build.sh dist -j32
          123
          • 編譯system.img,產物在qssi目錄下
          source build/envsetup.sh
          lunch xx-userdebug
          ./build.sh dist qssi_only -j32
          123
          • 編譯super.img
          source build/envsetup.sh
          lunch xx-userdebug
          ./build.sh dist merge_only -j32
          123
          • 編譯其它img,例如vendorimage,如果不指定會編譯其它所有img,產物在XX目錄下
          source build/envsetup.sh
          lunch xx-userdebug
          ./build.sh vendorimage dist target_only -j32
          
          1234


          3.5 動態分區刷機的方法

          由于Android Q版本以及以上將system和vendor分區合并為super分區,無法通過adb reboot bootloader模式單獨刷動態分區里面的img,例如system,vendor,product,odm等鏡像,只能刷super.img和其他的分區,但是super.img分區動輒幾個G的大小,每次刷機幾乎都要等上個好大幾分鐘,這個酸爽你懂的。

          這里有一點需要注意并不是說真的在bootloader模式下不能刷入system分區鏡像,可以看到下面的截圖是可以刷入的,但是只是鏡像沒有真的燒錄生效,所以讀者在實際開發中一定不要做無用功,否則一直燒錄,會發現咋咋我修改的東西沒有生效呢!


          那有沒有方法單刷呢,當然有了,不然我也不會多提一句不是。我們可以在fastboot模式下可以單獨刷動態分區里面的img,其方法如下:

          #推薦進入fastboot模式刷機:
          adb reboot fastboot
          fastboot getvar is-userspace
          is-userspace: yes
          Finished. Total time: 0.002s
          fastboot flash vendor vendor.img
          fastboot flash system system.img
          fastboot flash vbmeta vbmeta.img
          fastboot flash vbmeta_system vbmeta_system.img
          #fastbootd是用戶空間的代碼,因為動態的邏輯分區只能在應用空間識別
          12345678910

          1.如果是在linux下fastboot刷機出現權限問題,需要將fastboot的所有者屬性改成root
          sudo chown root:root fastboot
          sudo chmod +s fastboot
          2.如果是在windows環境下使用fastboot,很大概率可能不識別fastboot,此時推薦下載360的手機助手借助它安裝對應的驅動,這樣就能進行相關的識別了,此處是個人經驗
          3.并且我們在實際操作中需要,注意fastboot是否處于鎖定模式,否則會報一下錯誤(我調試的終端,已經強制鎖定了,所以那怕我強制執行了解鎖也一直報remote: 'Command not available on locked devices’的異常)
          4.我們來使用一個可以動態解鎖的fastboot,大功告成!



          3.6 Framework編譯

          對于從事Android偏向現Framework開發的讀者來說,編譯Android的Framework層是再常見不過的操作了,在Android R之上的Framework的編譯已經和之前有所不同,具體參見下面解釋:

          • Android R之前單獨編譯framework和service命令為:
          make -j8 framework
          make -j8 services
          12
          • Android R之后編譯services的命令還有效果,但是對于framework就有點力不從心了(因為編譯規則已經改變了),如下
          make -j8 framework-minus-apex
          make -j8 services
          12



          四.解決Android高版本編譯ssd固態硬盤空間不夠的問題

          ??對于Android開發者來說,當然希望自己在服務器上分配到的資源越多越好,特別是固態硬盤的容量,但是公司當開發者過多的時候,公司就會盡量壓縮ssd固態硬盤的盤符空間,只給分配了250G的固態硬盤容量,如果是同時開發編譯幾個Android低版本的源碼,那肯定是夠了,但是切到Android R之后,250G肯定是遠遠不夠的,這里我們通過du命令查看一下Android R編譯出來之后的情況,如下:

          ityuan@pd:~/ssd$ du   -sh    *
          
          260G	qcm2290
          ityuan@pd:~/ssd$ 
          ityuan@pd:~/ssd$ ls
          qcm2290
          ityuan@pd:~/ssd$ cd qcm2290/
          ityuan@pd:~/ssd/qcm2290$ du   -sh    *
          8.0K	about.html
          0	Android.bp
          85M	art
          64M	bionic
          218M	bootable
          0	bootstrap.bash
          24M	build
          0	build.sh
          3.4M	compatibility
          1.7G	cts
          26M	dalvik
          222M	developers
          150M	development
          635M	device
          4.0K	disregard
          7.1G	external
          1.9G	frameworks
          81M	hardware
          1.4G	kernel
          87M	libcore
          420K	libnativehelper
          4.0K	Makefile
          186G	out
          1.1G	packages
          3.4G	xxxdroid
          896K	pdk
          16M	platform_testing
          32G	prebuilts
          12K	product
          4.0K	readme.md
          232K	resources.arsc
          30M	sdk
          444K	shortcut-fe
          8.0K	sync.sh
          704M	system
          408M	test
          16K	TEST_BP
          9.7M	toolchain
          704M	tools
          6.9G	vendor
          
          12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849

          這里可以看到一個Android R的源碼工程就將整個的ssd硬盤空間占滿了,那么有什么辦法精簡呢。當然有了,我們可以對Android 的out目錄進行軟連接,鏈接到其它的分區之中。說干就干!下面我來記錄一下具體的步驟:

          • 建立軟鏈接目錄,這里我建立在我的根目錄下,如下:
          ityuan@pd:~$ mkdir out
          ityuan@pd:~$ ls out/
          ityuan@pd:~$ 
          123
          • 建立軟鏈接(對于建立軟鏈接還有不是很熟悉的讀者,可以參見博客Linux下創建軟鏈接)
          ityuan@pd:~$ ln -s /home/tangkw/out  /home/tangkw/ssd/qcm2290/out
          ityuan@pd:~$ cd ssd/qcm2290/
          ityuan@pd:~/ssd/qcm2290$ ll out
          lrwxrwxrwx 1 tangkw pd 16 Jan  5 16:54 out -> /home/tangkw/out/
          ityuan@pd:~/ssd/qcm2290$ 
          12345

          并且在創建軟鏈接中強烈建議使用絕對路徑,否則會提示Too many levels of symbolic links的錯誤

          • 查看成果,查看我們創建的out軟鏈接目錄,是否成功,如下:
          ityuan@pd:~$ cd out/
          ityuan@pd:~/out$ ls -l
          total 12684
          -rw-r--r-- 1 ityuan pd       0 Jan  5 16:56 Android.mk
          -rw-r--r-- 1 ityuan pd     160 Jan  5 16:59 build-bengal-cleanspec.ninja
          -rwxr-xr-x 1 ityuan pd      10 Jan  5 16:56 build_date.txt
          -rw-r--r-- 1 ityuan pd      10 Jan  5 16:56 build.trace.gz
          -rwxr-xr-x 1 ityuan pd       1 Jan  5 16:56 casecheck.txt
          -rwxr-xr-x 1 ityuan pd       1 Jan  5 16:56 CaseCheck.txt
          -rw-r--r-- 1 ityuan pd       0 Jan  5 16:56 CleanSpec.mk
          drwxr-xr-x 2 ityuan pd    4096 Jan  5 16:59 empty
          -rw-r--r-- 1 ityuan pd      39 Jan  5 16:59 env-bengal-cleanspec.sh
          -rw-r--r-- 1 ityuan pd       0 Jan  5 16:56 error.log
          drwxr-xr-x 3 ityuan pd    4096 Jan  5 17:00 host
          -rwxr-xr-x 1 ityuan pd 4309565 Jan  5 16:56 microfactory_Linux
          -rwxr-xr-x 1 ityuan pd     121 Jan  5 16:59 ninja-bengal-cleanspec.sh
          -rw-r--r-- 1 ityuan pd       0 Jan  5 16:56 ninja_build
          drwxr-xr-x 6 ityuan pd    4096 Jan  5 16:59 soong
          -rw-r--r-- 1 ityuan pd   19743 Jan  5 17:00 soong.log
          -rwxr-xr-x 1 ityuan pd 8580360 Jan  5 16:56 soong_ui
          drwxr-xr-x 3 ityuan pd    4096 Jan  5 16:59 target
          -rw-r--r-- 1 ityuan pd   24970 Jan  5 17:00 verbose.log.gz
          ityuan@pd:~/out$ 
          1234567891011121314151617181920212223
          • 接著查看下我們ssd目錄占用空間大小,如下(可以看到out目錄的大小已經為0了):
          ityuan@pd:~/ssd$ du -sh *
          75G	qcm2290
          ityuan@pd:~/ssd$ cd qcm2290/
          ityuan@pd:~/ssd/qcm2290$ 
          ityuan@pd:~/ssd/qcm2290$ 
          ityuan@pd:~/ssd/qcm2290$ du -sh *
          8.0K	about.html
          0	Android.bp
          85M	art
          64M	bionic
          218M	bootable
          0	bootstrap.bash
          24M	build
          0	build.sh
          3.4M	compatibility
          1.7G	cts
          26M	dalvik
          222M	developers
          150M	development
          635M	device
          4.0K	disregard
          7.1G	external
          1.9G	frameworks
          81M	hardware
          1.4G	kernel
          87M	libcore
          420K	libnativehelper
          4.0K	Makefile
          0	out
          1.1G	packages
          3.4G	xxxdroid
          896K	pdk
          16M	platform_testing
          32G	prebuilts
          12K	product
          4.0K	readme.md
          232K	resources.arsc
          30M	sdk
          444K	shortcut-fe
          8.0K	sync.sh
          704M	system
          408M	test
          16K	TEST_BP
          9.7M	toolchain
          704M	tools
          6.9G	vendor
          ityuan@pd:~/ssd/qcm2290$ 
          1234567891011121314151617181920212223242526272829303132333435363738394041424344454647

          大功告成,當然如果讀者是土豪公司,那這個就可以跳過不看了。



          五.Android為啥要引入動態分區

          ??在前面我們簡單說了下動態分區的概念,即在Android Q以及以后得編譯包中,我們找不到了對應的system,vendor等img文件,但是多了一個super.img,system,vendor,product,ODM合并為super分區,這個就是動態分區了。簡單來說就是為了在ota的時候能夠靈活創建分區和修改分區大小,將system,vendor,odm,product合并成super分區,并在super分區上預留出一定量的free space,這樣就可以動態調整這些分區的大小,解決了ota的時候分區不足,以及調整分區的風險.。



          當OTA升級之后,需要重新調整分區大小:


          碼字不易,覺得對你有幫助的話記得收藏順便小編點個贊哦 ^_^


          主站蜘蛛池模板: 国产精品视频一区| 久久国产香蕉一区精品| 无码精品人妻一区二区三区漫画| 免费视频精品一区二区| 夜精品a一区二区三区| 一区二区三区在线| 中文字幕一区精品| 亚洲国产一区二区a毛片| 日韩一区二区a片免费观看| 视频一区视频二区在线观看| 国产精品女同一区二区久久| 香蕉久久一区二区不卡无毒影院 | 免费一本色道久久一区| 精品一区二区三区3d动漫| 色视频综合无码一区二区三区| 亚洲福利视频一区二区| 日韩内射美女人妻一区二区三区| 麻豆精品人妻一区二区三区蜜桃 | 99精品国产一区二区三区2021| 亚洲一区二区三区丝袜| 日亚毛片免费乱码不卡一区| 精品亚洲综合在线第一区| 成人区精品一区二区不卡亚洲| 视频一区二区三区免费观看| 久久一本一区二区三区| 国产精品日韩一区二区三区| 久久se精品一区二区| 国产伦精品一区二区三区精品 | 青青青国产精品一区二区| 国产成人综合亚洲一区| 国产高清视频一区三区| 国产一区二区三区在线免费观看 | 精品一区二区三区在线播放| 国产成人无码精品一区二区三区| 一区二区在线视频免费观看| 精品无码人妻一区二区免费蜜桃 | 国产精品亚洲综合一区| AA区一区二区三无码精片| 久夜色精品国产一区二区三区| 欧美日韩精品一区二区在线视频 | 2020天堂中文字幕一区在线观 |