ReactNative 錯誤收集 (Bugly)
一、概述
APP的錯誤收集產品有很多,例如友盟統計、阿里雲等。本文討論的是由騰訊開發的Bugly。在使用的時候在網上找了一下,發現有一個外掛(https://github.com/canyara/react-native-bugly)。至於這個外掛的使用,我估計我的道行不夠吧,總之搞不通。然後在直接按照官方的文件配置的,可以統計了。
本文分三部分:第一部分是講解原理、第二部分是原理講解、第三部分是配置並演示。
二、原理講解
2.1 ReactNative 的編譯模式
在 ReactNative 的程式中,實際上執行的是 Js 的程式碼,而它也是分 Debug 和 Release 的。
在 Debug 模式下,會從本地開啟一個 Packager 服務,然後 App 執行起來之後,直接從服務里拉取最新的編譯後的 JS 程式碼,這樣可以在開發階段,做到程式碼實時更新的效果,只需要在裝置上,重新 Load 一下即可。
在 Release 模式下,ReactNative 會將 JS 程式碼,整體打包,然後放到 assets 目錄下,然後從這裡去載入 JS 程式碼。
這樣的邏輯被封裝在 ReactInstanceManager 類的 recreateReactContextInBackgroundInner()
方法中,有興趣可以自行看看。
ReactNative 在 Debug 的情況下,如果出現崩潰的 Bug,會直接出現紅屏,提示你崩潰的棧的具體資訊,這些內容可以幫助你快速的定位問題。如果在Release模式下,則出現閃退(或者ANR)。
2.2 Release 版本說明:
Android 舉例:
Android打包時會把,所有的JS檔案,混淆並且壓縮到asstes資料夾下的index.android.bundle中。圖:2.2-1
該檔案生成的原理是ReactNative使用瞭如下命令處理(node/modules/react.gradle 程式碼片段)
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine("cmd", "/c", *nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
"--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
} else {
commandLine(*nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
"--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
}
2.3 報錯說明(此處只說明原理,實現在第三章講解)
對於Debug模式下,報錯了直接紅屏並顯示報錯的地方。但是Release模式應用程式報錯則程式就崩潰了,無法查得原因。因此整合Bugly進行Bug收集。而使用Bugly收集Bug時得到是混淆並壓縮版的錯誤,這樣無法定位到錯誤的地方。
從圖中可以看出報錯的是344行、868列([email protected]:868),報錯原因是找不到變數(Can't find variable...),然後我們找到3.2步驟的壓縮檔案相應的地方。
可以在檔案中找到了此處,這裡能看到是Button找不到,但是這只是一個演示Demo當,內容不懂。當專案大了內容就多了,一個一個Button的找?所以得找到對映檔案。細節將在第三章講解。
三、配置、演示
切入正題,配置專案,整合Bugly。
3.1 前往Bugly配置APP資訊
(使用QQ登入,然後配置APP資訊獲取APP ID,傻瓜式的操作很容易)
3.2 Android專案配置
3.2.1 在android/app/build.gradle配置內容如下:
android {
...
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a", "x86"
}
packagingOptions {
exclude "lib/arm64-v8a/libimagepipeline.so"
}
}
...
dependencies {
...
compile 'com.tencent.bugly:crashreport:latest.release' //其中latest.release指代最新Bugly SDK版本號,也可以指定明確的版本號,例如2.2.0
compile 'com.tencent.bugly:nativecrashreport:latest.release' //其中latest.release指代最新Bugly NDK版本號,也可以指定明確的版本號,例如3.0
}
3.2.2 在MainApplication.java中修改如下:
匯入包
import com.tencent.bugly.crashreport.CrashReport;
在onCreate()方法中新增:
@Override
public void onCreate() {
super.onCreate();
CrashReport.initCrashReport(getApplicationContext(), "f7b76b8463", false); //新增此句話 f7b76b8463 為App Id
...
}
3.2.3 在AndroidManifest.xml中新增許可權
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_LOGS" />
3.2.4 執行示例
此處使用的測試Demo,大家可以自行搞一個報錯的進行演示。在DetailsScreen下使用Button元件,在此我將,Button不引入,導致報錯
將此APP簽名打包,執行時點選詳情頁,程式閃退。 開啟Bugly的控制檯,可以看到如下錯誤,在@342:1028 (分別表示行列)。
然後在專案的根目錄執行如下命令:(此處是生成對映檔案)
$ react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/ --sourcemap-output android-release.bundle.map
此時你會發現在專案的根目錄中出現android-release.bundle.map檔案,開啟可以看到裡面就是assets下的index.android.bundle對映檔案。
在專案根部新建檔案analyze/analyzeAndroid.js(此處的目的是使用node自帶的解析功能個)
在檔案中新增內容如下:
var sourceMap = require('source-map');
var fs = require('fs');
fs.readFile('../android-release.bundle.map', 'utf8', function (err, data) {
var smc = new sourceMap.SourceMapConsumer(data);
console.log(smc.originalPositionFor({
line: 344, //報錯的行
column: 868 //報錯的列
}));
});
執行JS會得到如下的內容:
可以看到定位到報錯的地方。
3.3 IOS 的配置
3.3.1 在ios目錄下新建檔案Podfile
填入如下內容:
target:"NavigationActions" do
pod 'Bugly'
end
NavigationActions為專案名,Bugly為新增的依賴,然後進入ios目錄下,執行命令:$ pod install (注意:執行此命令時請關閉所有Xcode的會話,模擬器一併關閉,防止撞鬼)
3.3.2 使用Xcode開啟檔案專案
開啟專案後點擊Product --> Clean 然後 再 Product --> Build (注意此步非常重要,因為新增了Bugly庫,不Build的專案會報錯)
Build後會提示錯誤:Library not fount for -LPods-專案名稱 例如下圖。
解決方案:
移除報錯的Library,然後重新Clean Build即可。
開啟AppDelegate.m檔案
在圖中的位置新增圖中的內容,#import <Bugly/Bugly.h>; 和 [Bugly startWithAppId:@"bf1eb7a4a9"];(bf1eb7a4a9為APP ID 注意IOS的Id和Android的ID不一樣)。
在Xcode的選單欄中,選擇Product --> Schame --> Edit Schame ...
執行Release版本。執行裝置上,同樣點選詳情按鈕,出現閃退。
3.3.3 執行示例
在Bugly控制檯中可以看到如下的錯誤:
可以看到報錯的行列分別是 344行 868列。
在專案的根目錄下執行命令(此處是生成對映檔案)
$ react-native bundle --platform ios --dev false --entry-file index.js --bundle-output ios-release.bundle --sourcemap-output ios-release.bundle.map
在專案的根目錄中可以看到多了個檔案ios-release.bundle,接著在專案根部新建檔案analyze/analyzeIOS.js(此處的目的是使用node自帶的解析功能個)
在檔案中新增內容如下:
var sourceMap = require('source-map');
var fs = require('fs');
fs.readFile('../ios-release.bundle.map', 'utf8', function (err, data) {
var smc = new sourceMap.SourceMapConsumer(data);
console.log(smc.originalPositionFor({
line: 344, //報錯的行
column: 868 //報錯的列
}));
});
執行JS會得到如下的內容:
可以看到定位到報錯的地方。
四、寫在後面的話
為了方便打擊更快整合Bugly所以寫下了這篇文章。創作不易,如果這邊文章對您有所幫助,就幫我點個贊,鼓勵下我吧。
最後感謝@承香墨影的部落格的部落格,本文很多地方出自他的內容,謝謝作者。
傳送門: