乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Android 借助 Python 實(shí)現(xiàn)自動(dòng)打包上傳 fir

       codingSmart 2021-10-22

      概述

      在開(kāi)發(fā)的過(guò)程中,很多時(shí)候完成了一個(gè)功能的開(kāi)發(fā),往往需要打包給測(cè)試進(jìn)行測(cè)試,之前就是打個(gè)包,要么是通過(guò) USB 進(jìn)行安裝,要么就是打個(gè)包通過(guò) QQ 給測(cè)試發(fā)送過(guò)去,后來(lái)接觸到 Jenkins,發(fā)現(xiàn)可以進(jìn)行持續(xù)集成,但是很多時(shí)候往往只是改了一個(gè)很小的功能,比如說(shuō)字體,或者顏色之類(lèi)的,Jenkins 就有點(diǎn)大材小用了,這個(gè)時(shí)候,總想著要是能夠通過(guò)腳本進(jìn)行自動(dòng)打包上傳至服務(wù)器并且生成一個(gè)下載的二維碼就好了,最近學(xué)習(xí)了 Python 并且也接觸了 fir 這個(gè)第三方托管工具,發(fā)現(xiàn),夢(mèng)想還是要有的,萬(wàn)一實(shí)現(xiàn)了呢

      關(guān)于 Python 和 fir

      關(guān)于Python

      Python 是一門(mén)高級(jí)編程語(yǔ)言,而且是一門(mén)動(dòng)態(tài)語(yǔ)言,可以用來(lái)編寫(xiě)各種腳本來(lái)幫助人們從一些重復(fù)性的操作中解放出來(lái),當(dāng)然也可以用來(lái)開(kāi)發(fā)網(wǎng)站,不過(guò)實(shí)現(xiàn) Python 的自動(dòng)打包上傳只需要準(zhǔn)備:

      了解基本的 Python 語(yǔ)法

      熟悉 Requests 這個(gè)網(wǎng)絡(luò)庫(kù)

      關(guān)于fir

      fir 是一個(gè)第三方的托管網(wǎng)站, 為開(kāi)發(fā)者提供測(cè)試應(yīng)用極速發(fā)布,應(yīng)用崩潰實(shí)時(shí)分析、用戶(hù)反饋收集等一系列開(kāi)發(fā)測(cè)試效率工具服務(wù),所以需要準(zhǔn)備的是

      注冊(cè)一個(gè)fir賬號(hào)

      了解fir對(duì)外提供的API

      流程

      注冊(cè)fir賬號(hào)

      fir的注冊(cè)地址是fir注冊(cè)地址,不過(guò)免費(fèi)的應(yīng)用每天提供的免費(fèi)下載次數(shù)是100次

      配置Python運(yùn)行環(huán)境

      Python 現(xiàn)在大致分為兩個(gè)大的版本:2.X以及3.X,不過(guò) Python 的3.X版本有些語(yǔ)法是不向下兼容的,由于對(duì) Python 不是很熟悉,所以還是選擇了2.7版本來(lái)配置環(huán)境,官網(wǎng)下載地址是 Python 官網(wǎng),我是Windows 系統(tǒng),所以下載的安裝包,然后下載了一個(gè)編輯 Python 的IDE 名字是 PyCharm,之所以選擇 IDE 沒(méi)有用 SublimeText 等文本編輯器是因?yàn)?windows 下的環(huán)境配置比較麻煩,而且剛開(kāi)始有 IDE 的提示不至于在一些小問(wèn)題上卡殼,當(dāng)然如果你愿意去配置文本編輯器,我推薦 SublimeText,提供了很多插件。

      編寫(xiě)Python腳本

      獲取上傳地址

      名稱(chēng)類(lèi)型標(biāo)題說(shuō)明

      typeStringios 或者 android(發(fā)布新應(yīng)用時(shí)必填)

      bundle_idStringApp 的 bundleId(發(fā)布新應(yīng)用時(shí)必填

      api_tokenString長(zhǎng)度為 32, 用戶(hù)在 fir 的 api_token

      服務(wù)器地址:http://api./apps()

      參數(shù)列表

      名稱(chēng)類(lèi)型標(biāo)題說(shuō)明

      typeStringios 或者 android(發(fā)布新應(yīng)用時(shí)必填)

      bundle_idStringApp 的 bundleId(發(fā)布新應(yīng)用時(shí)必填

      api_tokenString長(zhǎng)度為 32, 用戶(hù)在 fir 的 api_token

      Postman調(diào)試

      Python腳本編寫(xiě)

      import requests

      data = {'type''android''bundle_id''com.wustor.pythopackage',
              'api_token''9812fa28e4dac156673a5e45e7119631'}
      req = requests.post(url='http://api./apps', data=data)
      print req.content

      運(yùn)行測(cè)試

      {
          "id""5a059de3959d6961bb000257",
          "type""android",
          "short""asxn",
          "cert": {
              "icon": {
                  "key""5cc5942ccb1b7b86bd39c0f3ad84ea0c3e93a5e7",
                  "token""太長(zhǎng),以文字代替",
                  "upload_url""https://upload."
              },
              "binary": {
                  "key""63b159e5456d6151ace59ed7322d6942b05a4c6e.apk",
                  "token""太長(zhǎng),以文字代替",
                  "upload_url""https://upload."
              },
              "mqc": {
                  "total"5,
                  "used"0,
                  "is_mqc_availabled"true
              },
              "support""qiniu",
              "prefix""x:"
          }
      }

      上傳apk

      服務(wù)器地址:upload_url

      binary 字段對(duì)應(yīng)的 binary

      參數(shù)列表

      Postman進(jìn)行測(cè)試

      Python腳本編寫(xiě)

      # coding=utf-8
      import requests
      try:
          print("上傳apk")
          apk_path = 'F:/PythonDemo/Demo/app-release.apk'
          file = {'file': open(apk_path, 'rb')}
          param = {"key"'61a53809c7b58d8b68e537c3d4831b01325b1f0b.apk',
                   "token"'你自己的token',
                   "x:name"'測(cè)試',
                   "x:version"'1.0'"x:build"'1'"x:changelog"'暫無(wú)更新'}
          req = requests.post('https://upload.', files=file, data=param, verify=False)
          print 'success:' + req.content
      except Exception as e:
          print'error:' + e

      運(yùn)行測(cè)試

      {"is_completed":true}

      在fir界面查看結(jié)果

      界面顯示已經(jīng)上傳成功,但是發(fā)現(xiàn)沒(méi)有Logo,我開(kāi)始以為他會(huì)自動(dòng)提取apk中的logo,實(shí)際上并沒(méi)有,但是它提供了上傳logo的接口,現(xiàn)在來(lái)繼續(xù)上傳logo

      上傳應(yīng)用圖標(biāo)

      服務(wù)器地址:upload_url

      icon字段對(duì)應(yīng)的upload_url

      參數(shù)列表

      Postman測(cè)試

      fir查看上傳結(jié)果

      這里用了一張微信朋友圈的logo上傳,已經(jīng)成功替換。

      編寫(xiě)Python腳本

      # coding=utf-8
      import requests

      try:
          print("上傳icon")
          icon_path = 'F:/PythonDemo/Demo/demo.png'
          file = {'file': open(icon_path, 'rb')}
          param = {"key"'d1bca0636623f17782d9f851aa9e08c77f875a62',
                   'token''替換成你自己的token'
                   }
          req = requests.post('https://upload.', files=file, data=param, verify=False)
          print 'success:' + req.content
      except Exception as e:
          print'error:' + e

      運(yùn)行結(jié)果

      {"is_completed":true}

      編寫(xiě)gradle腳本

      task debugToFir {
              dependsOn 'assembleDebug'
              doLast {
                  def upUrl = "http://api./apps"
                  def appName = "Python2"
                  def bundleId = project.android.defaultConfig.applicationId
                  def verName = project.android.defaultConfig.versionName
                  def apiToken = "9812fa28e4dac156673a5e45e7119631"
                  def iconPath = "F:/PythoPackage/app/src/main/res/mipmap-xxhdpi/ic_launcher.png"
                  def apkPath = "F:/PythoPackage/app/build/outputs/apk/debug/app-debug.apk"
                  def buildNumber = project.android.defaultConfig.versionCode
                  def changeLog = "版本更新日志"
                  //執(zhí)行Python腳本
                  def process = "python upToFir.py ${upUrl} ${appName} ${bundleId} ${verName} ${apiToken} ${iconPath} ${apkPath} ${buildNumber} ${changeLog}".execute()
                  println("開(kāi)始上傳至fir")
                  //獲取Python腳本日志,便于出錯(cuò)調(diào)試
                  ByteArrayOutputStream result = new ByteArrayOutputStream()
                  def inputStream = process.getInputStream()
                  byte[] buffer = new byte[1024]
                  int length
                  while ((length = inputStream.read(buffer)) != -1) {
                      result.write(buffer, 0length)
                  }
                  println(result.toString("UTF-8"))
                  println "上傳結(jié)束 "
              }
          }

      該腳本放在 app/build.gradle 中的 android 目錄下

      統(tǒng)一Python腳本

      # coding=utf-8
      # encoding = utf-8
      import requests
      import sys
      def upToFir():
          # 打印傳遞過(guò)來(lái)的參數(shù)數(shù)組長(zhǎng)度,便于校驗(yàn)
          print 'the argLength--->:' + len(sys.argv)
          upUrl = sys.argv[1]
          appName = sys.argv[2]
          bundleId = sys.argv[3]
          verName = sys.argv[4]
          apiToken = sys.argv[5]
          iconPath = sys.argv[6]
          apkPath = sys.argv[7]
          buildNumber = sys.argv[8]
          changeLog = sys.argv[9]
          queryData = {'type': 'android', 'bundle_id': bundleId, 'api_token': apiToken}
          iconDict = {}
          binaryDict = {}
          # 獲取上傳信息
          try:
              response = requests.post(url=upUrl, data=queryData)
              json = response.json()
              iconDict = (json["cert"]["icon"])
              binaryDict = (json["cert"]["binary"])
          except Exception as e:
              print('query:' + e)

          # 上傳apk
          try:
              file = {'file': open(apkPath, 'rb')}
              param = {"key": binaryDict['key'],
                       'token': binaryDict['token'],
                       "x:name": appName,
                       "x:version": verName,
                       "x:build": buildNumber,
                       "x:changelog": changeLog}
              req = requests.post(url=binaryDict['upload_url'], files=file, data=param, verify=False)
              print 'success_apk:' + req.content
          except Exception as e:
              print'error_apk:' + e

          # 上傳logo
          try:
              file = {'file': open(iconPath, 'rb')}
              param = {"key": iconDict['key'],
                       'token': iconDict['token']}
              req = requests.post(url=iconDict['upload_url'], files=file, data=param, verify=False)
              print 'success_icon:' + req.content
          except Exception as e:
              print'error_icon:' + e


      if __name__ == '__main__':
          upToFir()

      前面的三個(gè) python 腳本的參數(shù)都是寫(xiě)死的,所以需要改變成動(dòng)態(tài)從 gradle 中獲取,獲取的時(shí)候先判斷一下數(shù)組長(zhǎng)度,看看是不是跟之前約定的一樣

      整體進(jìn)行測(cè)試

      這個(gè)時(shí)候修改一下apk的一些參數(shù),跟logo

      versionCode 3
      versionName "1.2"
      iconPath=ic_launcher.png
      appName="python"

      執(zhí)行g(shù)radle命令 gradlew debugToFir,運(yùn)行結(jié)果

      開(kāi)始上傳至fir
      http://api./apps
      success_apk:{"is_completed":true}
      success_icon:{"is_completed":true}
      上傳結(jié)束 with value 0

      運(yùn)行成功,到官網(wǎng)查看結(jié)果

      完美,簡(jiǎn)單,以后簡(jiǎn)單的打包就用一行代碼就可以搞定了,吼吼。

      小結(jié)

      其實(shí) Python 的語(yǔ)法很簡(jiǎn)潔,作為一門(mén)動(dòng)態(tài)語(yǔ)言,不需要像 Java 定義各種類(lèi)型變量,gradle 的語(yǔ)法其實(shí)也一樣,掌握這兩種語(yǔ)言的基本用法,有助于更高效的開(kāi)發(fā) Android。

      源碼下載 https://github.com/wustor/PythoPackage

      與之相關(guān)

      6 天時(shí)間修改 1 行代碼:現(xiàn)實(shí)中的軟件開(kāi)發(fā)流程

      編程之旅,致新入行的朋友

      如何閱讀代碼(八點(diǎn)要記牢)

        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多