在這里先給大家拜個晚年,雖然說新已經(jīng)過了
。本文是今天第一篇文章,已經(jīng)有好長時間沒總結(jié)了,算了給2017開個好頭吧。之前一直搞不懂什么是熱修復(fù)?其實熱修復(fù)就是在應(yīng)用不用重新安裝的情況下更新應(yīng)用。最多的應(yīng)用場景就是用來修復(fù)bug。因為重新發(fā)包的代價太大了,所以我們可以選擇用熱修復(fù)來修復(fù)bug!需要注意的一點是Tinker在1.7.6版本以及之后的版本不支持加固后的動態(tài)更新,所以用了這個就不用用其他廠商的加固服務(wù),只能使用so文件等更安全的方式來使應(yīng)用更安全!在這里附上官網(wǎng)指南:https://github.com/Tencent/tinker/wiki
一、添加gradle依懶
在項目build.gradle中添加以下代碼
dependencies { classpath 'com.android.tools.build:gradle:2.2.0' //tinker依懶 classpath "com.tencent.tinker:tinker-patch-gradle-plugin:${TINKER_VERSION}" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files }別忘了還要在項目的gradle.PRoperties中添加以下變量TINKER_VERSION=1.7.7然后在app/build.gradle中添加從Tinker模板(點擊去復(fù)制代碼)中拷貝代碼到里面去
當(dāng)配置完成,點擊Sync Now,bug就出來了,這是大部分人會遇到的問題!如下圖

出現(xiàn)這個問題的原因是沒有正確的配置ide的git路徑(官方解釋),不過我配置了還是不行!這里最簡單的辦法就是給它設(shè)置一個值,如下圖
二,編寫生成Application的類,因為SimpleTinkerInApplicationLike會在編譯期生成SimpleTinkerInApplication。
@DefaultLifeCycle(application = ".SimpleTinkerInApplication", flags = ShareConstants.TINKER_ENABLE_ALL, loadVerifyFlag = false)public class SimpleTinkerInApplicationLike extends ApplicationLike { public SimpleTinkerInApplicationLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) { super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent); } @Override public void onBaseContextAttached(Context base) { super.onBaseContextAttached(base); } @Override public void onCreate() { super.onCreate(); TinkerInstaller.install(this); }}別忘了添加到清單文件里去
<application android:name=".SimpleTinkerInApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/APPTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application>三、編寫MainActivity,很簡單,就一行代碼public class MainActivity extends AppCompatActivity { private TextView mTextView; private Button mButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.tv); mButton = (Button) findViewById(R.id.btn);// mTextView.setText("這不是bug"); mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip.apk");//等下要push到SD卡里面去apk,以達(dá)到更新的目的 } }); }}xml文件如下<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.kuyue.tinkertest.MainActivity" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="這是個bug"/> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="點我修復(fù)bug"/></LinearLayout>四,安裝“有bug”的應(yīng)用
這里不能直接點運行,要選擇assembleDebug。這時會在app/build/bakApk下生成編譯好的安裝包(編譯時會報錯,需要把debug時的簽名文件放到相應(yīng)路徑里面,一般我們debug不需要簽名文件,所以只需要把與debug簽名相關(guān)的代碼注釋即可),然后將該安裝包安裝到手機(jī)上。可以使用adb命令將安裝包安裝到手機(jī)。如果應(yīng)用已經(jīng)在手機(jī)上已經(jīng)安裝了,那么就要使用這個命令。(如果提示不是內(nèi)部命令則需要將adb.exe所在的文件地址添加到電腦的系統(tǒng)變量Path里面去)

沒有在手機(jī)上安裝過的則使用這個命令:adb install app/build/bakApk/app-debug-0207-10-35-25.apk。
安裝成功之后,打開應(yīng)用,出現(xiàn)如下的界面,很簡單的界面!

五、生成補丁包及修復(fù)“bug”
將MainActivity里面注釋掉的代碼放出來,沒錯,就是“這不是bug”那一句!
然后需要將上一步生成的安裝包的路徑拷到oldApk參數(shù)里面去

雙擊tinkerPatchDebug任務(wù)
任務(wù)完成后,會在/build/outputs/tinkerPatch/生成補丁包,然后我們需要將patch_signed_7zip.apk推送到sd卡的中。
adb push ./app/build/outputs/tinkerPatch/debug/patch_signed_7zip.apk /storage/sdcard0/有可能會報Permission denied錯誤,目前沒有解決,可以選擇直接復(fù)制到手機(jī)sdcard的主目錄。推送完成之后,則點擊“點我修復(fù)BUG”按鈕,應(yīng)用自動退出,觀察log,log會打印提示更新成功,再次啟動應(yīng)用,見證奇跡的時候到了,這時候bug已經(jīng)不見了!

到這里,接入的流程基本完成了。不知道大家發(fā)現(xiàn)一個問題沒有,那我怎么知道應(yīng)用更新補丁成功?并且也不能讓應(yīng)用自動退出啊!這樣的用戶體驗太差了。所以我們需要解更新完補丁后應(yīng)用自動退出和監(jiān)聽補丁更新完的問題!需要解決這樣的問題,可以參考Tinker官網(wǎng)的demo,添加一個service:SampleResultService。
六、打release包
步驟類似上面的四,不過這里要將里面的keystore配置更改成自己的,然后再雙擊assembleRelease任務(wù),編譯成功之后會在bakApk里面生成相應(yīng)的文件,然后再將這三個文件的路徑添加到grale里面,如下圖

然后再雙擊tinkerPatchRelease任務(wù),和上面的debug一樣,會生成patch_signed_7zip.apk補丁包!剩下的就和debug的一樣了!
最后放上github地址:https://github.com/kuyue/TinkerTest/tree/master
新聞熱點
疑難解答