Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android OTA升級包制作腳本詳解(一,參數解析)

Android OTA升級包制作腳本詳解(一,參數解析)

編輯:關於Android編程

寫在前面:

“build/tools/releasetools/ota_from_target_files -u lk.bin -n target.zip update.zip”這是制作整包的命令,很顯然這裡支持lk升級。本系列博文主要對該命令的執行流程及原理進行一個系統的分析,涉及到/build/tools/releasetools/目錄下多個模塊如ota_from_target_files、common等。由於本人對python了解粗淺,文中所涉及到的python語法大都做了注釋,以便幫助部分對python有興趣的同學能夠讀懂相應的語句。

整個流程看起來有些繁瑣冗雜,希望有興趣的同學能夠耐心的去看,已經比較熟悉python語法的同學可以挑選感興趣的部分作為參考。

一,執行腳本

那麼首先,我們從命令中可以看到整包的制作流程是從ota_from_target_files模塊開始的。而ota_from_target_files模塊最先執行的方法是從下面這段語句開始的,如下:

#__name__作為模塊的內置屬性,指.py文件的調用方式;.py文件有兩種使用方式:作為模塊被調用和直接使用。如果它等於__main__就表示是直接執行。也就是說在if __name__ == __main__:之後的語句作為模塊被調用的時候不執行;直接使用的時候,語句之後的代碼執行。而這裡很顯然是直接使用。

 

if __name__ == '__main__':
  try:
    common.CloseInheritedPipes()MAC系統中卻是一些描述文件(PIPE),這裡在開始之前關閉fds;這裡主要是根據當前所使用的操作系統做的一些調整
    main(sys.argv[1:])這是編譯腳本主要的方法
  except common.ExternalError, e:
    print
    print    ERROR: %s % (e,)
    print
    sys.exit(1)
下面是腳本的入口函數main(arg)

 

 

def main(argv):
  將用戶設定的 Option 存入 OPTIONS 變量中。OPTIONS是一個Python Class, 我們將其理解為一個C Struct或者一個java的封裝即可
  def option_handler(o, a):
    if o in (-b, --board_config):#in是一個布爾操作符,用來測試左邊的操作數是否包含於右邊的元祖,這裡用來判斷參數o所傳入的值是否包含在(-b, --board_config)中;
      pass   # deprecated
    elif o in (-k, --package_key):
      OPTIONS.package_key = a
    elif o in (-i, --incremental_from):
      OPTIONS.incremental_source = a
    elif o in (-w, --wipe_user_data):
      OPTIONS.wipe_user_data = True
    elif o in (-n, --no_prereq):
      OPTIONS.omit_prereq = True
    elif o in (-e, --extra_script):
      OPTIONS.extra_script = a
    elif o in (-a, --aslr_mode):
      if a in (on, On, true, True, yes, Yes):
        OPTIONS.aslr_mode = True
      else:
        OPTIONS.aslr_mode = False
    elif o in (--worker_threads):
      OPTIONS.worker_threads = int(a)
    elif o in (-2, --two_step):
      OPTIONS.two_step = True
    elif o in (-r, --preloader):
      OPTIONS.preloader = a
    elif o in (-l, --logo):
      OPTIONS.logo = a
    elif o in (-u, --uboot):
      OPTIONS.uboot = a
    elif o in (-d, --dsp):
      OPTIONS.dsp = a
    elif o in (-f, --special_factory_reset):
      OPTIONS.special_factory_reset = True
    elif o in (-g, --ubifs):
      OPTIONS.ubifs = True  
    elif o in (-t, --tee):
      OPTIONS.tee = a 
    elif o in (-z, --trustonic):
      OPTIONS.trustonic = a
    else:
      return False
    return True

二,解析參數

 

 

  #解析參數
  args = common.ParseOptions(argv, __doc__,
                             extra_opts=b:k:i:d:wfgne:r:l:u:t:z:d:a:s:2,
                             extra_long_opts=[board_config=,
                                              package_key=,
                                              incremental_from=,
                                              wipe_user_data,
                                              special_factory_reset,
                                              ubifs,
                                              no_prereq,
                                              extra_script=,
                                              preloader=,
                                              logo=,
                                              uboot=,
                                              tee=,
                                              trustonic=,
                                              dsp=,
                                              worker_threads=,
                                              aslr_mode=,
                                              two_step,
                                              ],
                             extra_option_handler=option_handler)
上面解析參數的操作實際上是封裝在了common.py模塊來進行,這裡我們對extra_option_handler=option_handler簡單的解釋一下,在Python中函數是可以直接復制給一個變量的,option_handler是上面定義的一個方法,而這裡並沒有執行,而是直接賦值給了extra_option_handler,而且我們需要注意的是賦值並不會執行option_handler中內容,而是在實際調用的時候才會執行。那麼既然變量可以指向函數,所以一個函數可以接收另外一個函數作為參數。

 

那麼我們接著來了解函數解析的流程,首先看代碼:

#在python中,getopt模塊是專門用來處理命令行參數的,這裡args是個列表,包含那些沒有-或--的參數,格式如下['target.zip','update.zip'],而opts是個包含元祖的列表,每個元祖是分析出來的格式信息,如[('-u', 'lk.bin'),('-n', ''),('-i', 'base.zip')] ;如果想了解getopt具體的邏輯請參考這篇博文python中getopt的使用。

 

#解析參數
def ParseOptions(argv,
                 docstring,
                 extra_opts=, extra_long_opts=(),
                 extra_option_handler=None):
  Parse the options in argv and return any arguments that aren't
  flags.  docstring is the calling module's docstring, to be displayed
  for errors and -h.  extra_opts and extra_long_opts are for flags
  defined by the caller, which are processed by passing them to
  extra_option_handler.

  try:
    opts, args = getopt.getopt(
        argv, hvp:s:x: + extra_opts,
        [help, verbose, path=, signapk_path=, extra_signapk_args=,
         java_path=, public_key_suffix=, private_key_suffix=,
         device_specific=, extra=] +
        list(extra_long_opts))
		
		
	#那麼我們可以在這裡添加log來查看opts、args中的值
	print(begin)
	for i in range(len(opts)):
	    print(opts[i])
	print(************)
	for i in range(len(args)):
	    print(args[i])
	print(end)
	
	
  except getopt.GetoptError, err:
    Usage(docstring)
    print **, str(err), **
    sys.exit(2)

  path_specified = False

  for o, a in opts:
    if o in (-h, --help):
      Usage(docstring)
      sys.exit()
    elif o in (-v, --verbose):
      OPTIONS.verbose = True
    elif o in (-p, --path):
      OPTIONS.search_path = a
    elif o in (--signapk_path,):
      OPTIONS.signapk_path = a
    elif o in (--extra_signapk_args,):
      OPTIONS.extra_signapk_args = shlex.split(a)
    elif o in (--java_path,):
      OPTIONS.java_path = a
    elif o in (--public_key_suffix,):
      OPTIONS.public_key_suffix = a
    elif o in (--private_key_suffix,):
      OPTIONS.private_key_suffix = a
    elif o in (-s, --device_specific):
      OPTIONS.device_specific = a
    elif o in (-x, --extra):
      key, value = a.split(=, 1)
      OPTIONS.extras[key] = value
    else:
      if extra_option_handler is None or not extra_option_handler(o, a):
        assert False, unknown option %s % (o,)
  #環境變量
  os.environ[PATH] = (os.path.join(OPTIONS.search_path, bin) +
                        os.pathsep + os.environ[PATH])

  return args

 

下面是具體log打印的信息:

 

begin
('-u', 'lk.bin')
('-n', '')
('-i', 'base.zip')
******
target.zip
update.zip
end
那麼參數解析完畢之後,執行流程繼續回到ota_from_target_files中的main函數。我們順著流程接著看。

 

下面是對完成參數解析的返回值的長度進行一個過濾,這裡固定是2,無論是整包或者差分包的制作。

  if len(args) != 2:
    common.Usage(__doc__)
    sys.exit(1)
#這裡沒有額外的腳本,因此OPTIONS.extra_script的值為None。
  if OPTIONS.extra_script is not None:
    OPTIONS.extra_script = open(OPTIONS.extra_script).read()
 

 


 

 

 

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved