引入 Tinker 之後如何在 Debug 模式下開啟 Instant Run

来源:https://www.cnblogs.com/cspecialy/archive/2018/06/09/9160850.html
-Advertisement-
Play Games

在《Tinker + Bugly + Jenkins 爬坑之路》一文中講了在接入 Tinker 之後,Jenkins 中的一些坑,由此,熱修複算告一段落,但是,在直接 Run 模式運行時,程式會報出如下錯誤: 好吧,使用 TInker 時不能開啟 Instant Run  ̄□ ̄|| GitHub 上 ...


在《Tinker + Bugly + Jenkins 爬坑之路》一文中講了在接入 Tinker 之後,Jenkins 中的一些坑,由此,熱修複算告一段落,但是,在直接 Run 模式運行時,程式會報出如下錯誤:

Tinker does not support instant run mode, please trigger build by assembleDebug or disable instant run in 'File->Settings...'.

好吧,使用 TInker 時不能開啟 Instant Run  ̄□ ̄||

GitHub 上也有一個同樣的 issue,引入Tinker之後如何在Debug模式下開啟Instant Run ,這裡我將我的方法講述一下,給大家一個參考。

1. 使用變數標記是否使用 Tinker

projectbuild.gradle 文件的 ext 中定義變數 tinkerEnabled 用來標記是否使用 TInker,代碼如下所示:

ext {
/**
* 是否啟用tinker參與編譯
* 開發時,根據需要修改值來開啟
* Jenkins 構建時,會替換該值
*/

tinkerEnabled = rootProject.properties["tinkerEnable"]
if (null == tinkerEnabled) {
tinkerEnabled = "false"
}
}

看過《Tinker + Bugly + Jenkins 爬坑之路》的同學應該知道,我司的項目是使用 Jenkins 打包的,所以我這裡先通過 rootProject.properties["tinkerEnable"] 從 Gradle 命令中取 tinkerEnabled 參數的值,然後在構建腳本的打包命令行中加入該參數:

sh gradlew assembleRelease -PtinkerEnable=true --stacktrace

這樣,就確保了 Jenkins 構建時 tinkerEnable 的值為 true。在開發過程中,本地運行或者構建 apk 就可以通過修改 tinkerEnabled = "false" 來決定是否使用 Tinker 構建。

2. 通過標記值決定是否使用 TInker 構建

接下來在 modulebuild.gradle 文件中,通過 tinkerEnabled 值來判斷是否引入 tinker-support.gradle 構建項目,代碼如下:

// 依賴插件腳本-tinker
if (Boolean.parseBoolean(rootProject.ext.tinkerEnabled)) {
apply from: rootProject.file('gradle/tinker-support.gradle')
}

3. Java/Kotlin 代碼中通過標記值決定是否初始化 Tinker

Java/Kotlin 代碼中,是無法直接使用 gradle 文件中的變數值的,那麼在 Java/Kotlin 代碼中,怎麼通過上面定義的標記量來決定是否初始化 Tinker 呢?總不能在 Java/Kotlin 代碼中也定義一個全局變數來控制吧,那樣本地開發時一改就得改兩個地方,不但麻煩而且可能出錯,另外,Jenkins 打包時也無法確定 Java/Kotlin 會初始化 Tinker。

那,怎麼辦呢?我們來個“曲線救國”的方法。通過自定義 BuildConfig 屬性來解決,首先,在 modulebuild.gradle 文件中,將 tinkerEnabled 的值傳遞到 BuildConfig 的自定義屬性中,代碼如下:

android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
/** =============自定義 BuildConfig 屬性========================*/
buildConfigField "boolean", "BuildConfig", rootProject.ext.tinkerEnabled
/** =============自定義 BuildConfig 屬性========================*/
}
}

然後,在自定義的 application 類中添加根據 BuildConfig.BuildConfig 判斷是否初始化 Tinker 的代碼:

package com.cy.sample

import android.app.Application
import android.content.Context
import android.widget.Toast
import com.tencent.bugly.Bugly
import com.tencent.bugly.beta.Beta
import com.tencent.bugly.beta.interfaces.BetaPatchListener
import com.tencent.bugly.beta.tinker.TinkerManager.getApplication
import java.util.*

/**
* 類描述。
*
* @author cspecialy
* @version v1.0.0
*/

class MyApplication : Application() {

override fun onCreate() {
super.onCreate()
if (BuildConfig.TINKER_ENABLE) {
initTinker()
}
}

/**
* 初始化 Tinker
*/

private fun initTinker() {
// 設置是否開啟熱更新能力,預設為true
Beta.enableHotfix = true
// 設置是否自動下載補丁,預設為true
Beta.canAutoDownloadPatch = true
// 設置是否自動合成補丁,預設為true
Beta.canAutoPatch = true
// 設置是否提示用戶重啟,預設為false
Beta.canNotifyUserRestart = true
// 補丁回調介面
Beta.betaPatchListener = object : BetaPatchListener {
override fun onPatchReceived(patchFile: String) {
Toast.makeText(getApplication(), "補丁下載地址$patchFile", Toast.LENGTH_SHORT).show()
}

override fun onDownloadReceived(savedLength: Long, totalLength: Long) {
Toast.makeText(getApplication(),
String.format(Locale.getDefault(), "%s %d%%",
Beta.strNotificationDownloading,
(if (totalLength == 0L) 0 else savedLength * 100 / totalLength).toInt()),
Toast.LENGTH_SHORT).show()
}

override fun onDownloadSuccess(msg: String) {
Toast.makeText(getApplication(), "補丁下載成功", Toast.LENGTH_SHORT).show()
}

override fun onDownloadFailure(msg: String) {
Toast.makeText(getApplication(), "補丁下載失敗", Toast.LENGTH_SHORT).show()

}

override fun onApplySuccess(msg: String) {
Toast.makeText(getApplication(), "補丁應用成功", Toast.LENGTH_SHORT).show()
}

override fun onApplyFailure(msg: String) {
Toast.makeText(getApplication(), "補丁應用失敗", Toast.LENGTH_SHORT).show()
}

override fun onPatchRollback() {

}
}

// 設置開發設備,預設為false,上傳補丁如果下發範圍指定為“開發設備”,需要調用此介面來標識開發設備
Bugly.setIsDevelopmentDevice(getApplication(), true)
// 多渠道需求塞入
// String channel = WalleChannelReader.getChannel(getApplication());
// Bugly.setAppChannel(getApplication(), channel);
// 這裡實現SDK初始化,appId替換成你的在Bugly平臺申請的appId
Bugly.init(getApplication(), "2a1dc56c3a", true)
}

override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
// you must install multiDex whatever tinker is installed!
MultiDex.install(base)

if (BuildConfig.TINKER_ENABLE) {
// 安裝tinker
Beta.installTinker()
}
}
}

以上代碼相信大家也註意到了,是的,我這裡 TInker 是使用 enableProxyApplication = true 開啟反射代理的方式,大家如果使用 enableProxyApplication = false 方式的話,方向也一樣,我這裡就不贅述了,大家因地制宜哈~~~ O(∩_∩)O哈哈~

接下來,開發時只需要將 tinkerEnabled 變數的值設置為 false,就可以愉快的使用 Instant Run 了。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 背景 由於項目的需要,使用 資料庫,因此在Windows上安裝 資料庫。但是在安裝後,無法訪問本地資料庫,這個時候查看 目錄,沒有任何文件。而且安裝過程中,彈出提示框 Problem running post install step.Installation may not complete co ...
  • 在鎖與事務系列里已經寫完了上篇中篇,這次寫完下篇。這個系列俺自認為是有條不紊的進行,但感覺鎖與事務還是有多很細節沒有講到,溫故而知新可以為師矣,也算是一次自我提高總結吧,也謝謝大伙的支持。在上一篇的末尾寫了事務隔離級別的不同表現,還沒寫完,只寫到了重覆讀的不同隔離表現,這篇繼續寫完序列化,快照的不同 ...
  • 一、表關係 先參照如下表結構創建7張表格,並創建相關約束 年級表: class_grade 1. 班級表class create table class ( cid int primary key auto_increment, caption char(10), grade_id int ); i ...
  • 第一步:使用記事本打開mysql安裝目錄下的"my.ini”文件。 看看default-character-set 是不是 utf8不是的話 改為utf8即可!(以前的版本可能沒有這句話 直接加上就好了!) 第二步:在mysql資料庫cmd中輸入:show variables like'%char% ...
  • zookeeper的安裝分為三種模式:單機模式、集群模式和偽集群模式。 1、單機模式 首先,從Apache官網下載一個Zookeeper穩定版本,本次教程採用的是zookeeper-3.4.9版本。 http://apache.fayea.com/zookeeper/zookeeper-3.4.9/ ...
  • 前言 1.操作系統為Centos7 2.所有操作都是使用root用戶去操作。也可以使用其他用戶,非root的話要註意操作的許可權問題。 3.安裝的Hadoop版本是2.6.5,Spark版本是2.2.0,Scala的版本是2.11.8。 如果安裝的Spark要同Hadoop搭配工作,則需註意他們之間的 ...
  • 聚合(aggregate): db.集合.aggregate([{管道:{表達式}}]) db.集合.aggregate([ {管道1:{表達式1}}, {管道2:{表達式2}}, ... ...]) 管道1的結果作為管道2的輸入. $group:分組 {$group:{ _id:'$gender' ...
  • 三元素:資料庫 集合 文檔(json的擴展bson) 服務啟動重啟停止: sudo service mongodb start(stop,restart) 修改配置文件 /etc/mongodb.conf添加 smallfiles=true 查看當前資料庫 db 查看所有資料庫 show dbs 查 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...