Commit 3f45a30f23cb804378a9fe6901f58abf016aaaca
1 parent
bda8fbad
feat:集成友盟APM(flutter侧)
Showing
7 changed files
with
117 additions
and
6 deletions
android/app/proguard-rules.pro
| @@ -24,4 +24,22 @@ | @@ -24,4 +24,22 @@ | ||
| 24 | -keep class com.tt.** { *; } | 24 | -keep class com.tt.** { *; } |
| 25 | -keep class com.xs.** { *; } | 25 | -keep class com.xs.** { *; } |
| 26 | -keep interface com.xs.** { *; } | 26 | -keep interface com.xs.** { *; } |
| 27 | --keep enum com.xs.** { *; } | ||
| 28 | \ No newline at end of file | 27 | \ No newline at end of file |
| 28 | +-keep enum com.xs.** { *; } | ||
| 29 | + | ||
| 30 | +# 友盟混淆 | ||
| 31 | +-keep class com.umeng.** { *; } | ||
| 32 | + | ||
| 33 | +-keep class com.uc.** { *; } | ||
| 34 | + | ||
| 35 | +-keep class com.efs.** { *; } | ||
| 36 | + | ||
| 37 | +-keepclassmembers class *{ | ||
| 38 | + public<init>(org.json.JSONObject); | ||
| 39 | +} | ||
| 40 | +-keepclassmembers enum *{ | ||
| 41 | + publicstatic**[] values(); | ||
| 42 | + publicstatic** valueOf(java.lang.String); | ||
| 43 | +} | ||
| 44 | +-keep public class com.kouyuxingqiu.wow_english.R$*{ | ||
| 45 | + publicstaticfinalint*; | ||
| 46 | +} | ||
| 29 | \ No newline at end of file | 47 | \ No newline at end of file |
android/app/src/main/AndroidManifest.xml
| @@ -24,6 +24,8 @@ | @@ -24,6 +24,8 @@ | ||
| 24 | <intent-filter> | 24 | <intent-filter> |
| 25 | <action android:name="android.intent.action.MAIN"/> | 25 | <action android:name="android.intent.action.MAIN"/> |
| 26 | <category android:name="android.intent.category.LAUNCHER"/> | 26 | <category android:name="android.intent.category.LAUNCHER"/> |
| 27 | + <!-- 友盟apm集成测试用 --> | ||
| 28 | + <data android:scheme="um.663b66b0b3362515012f4ea5" /> | ||
| 27 | </intent-filter> | 29 | </intent-filter> |
| 28 | </activity> | 30 | </activity> |
| 29 | <!-- Don't delete the meta-data below. | 31 | <!-- Don't delete the meta-data below. |
android/app/src/main/kotlin/com/kouyuxingqiu/wow_english/MainActivity.kt
| @@ -61,6 +61,8 @@ class MainActivity : FlutterActivity() { | @@ -61,6 +61,8 @@ class MainActivity : FlutterActivity() { | ||
| 61 | * 友盟初始化 | 61 | * 友盟初始化 |
| 62 | */ | 62 | */ |
| 63 | private fun initUmeng() { | 63 | private fun initUmeng() { |
| 64 | + // 友盟集成测试阶段获取UMID | ||
| 65 | +// android.util.Log.d("WQF UMConfigure", UMConfigure.getUMIDString(this)) | ||
| 64 | // 在application.onCreate内配置各模块开关并预初始化SDK | 66 | // 在application.onCreate内配置各模块开关并预初始化SDK |
| 65 | // 重点关注:如果您还想采集Native 崩溃、ANR等日志可以参考下面设置 | 67 | // 重点关注:如果您还想采集Native 崩溃、ANR等日志可以参考下面设置 |
| 66 | UMCrash.initConfig(Bundle().apply { | 68 | UMCrash.initConfig(Bundle().apply { |
build.yaml
0 → 100644
lib/app/app.dart
| @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; | @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; | ||
| 3 | import 'package:flutter_easyloading/flutter_easyloading.dart'; | 3 | import 'package:flutter_easyloading/flutter_easyloading.dart'; |
| 4 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 4 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
| 5 | import 'package:responsive_framework/responsive_framework.dart'; | 5 | import 'package:responsive_framework/responsive_framework.dart'; |
| 6 | +import 'package:umeng_apm_sdk/umeng_apm_sdk.dart'; | ||
| 6 | import 'package:wow_english/common/blocs/cachebloc/cache_bloc.dart'; | 7 | import 'package:wow_english/common/blocs/cachebloc/cache_bloc.dart'; |
| 7 | import 'package:wow_english/common/widgets/hide_keyboard_widget.dart'; | 8 | import 'package:wow_english/common/widgets/hide_keyboard_widget.dart'; |
| 8 | import 'package:wow_english/pages/tab/blocs/tab_bloc.dart'; | 9 | import 'package:wow_english/pages/tab/blocs/tab_bloc.dart'; |
| @@ -10,7 +11,9 @@ import 'package:wow_english/pages/user/bloc/user_bloc.dart'; | @@ -10,7 +11,9 @@ import 'package:wow_english/pages/user/bloc/user_bloc.dart'; | ||
| 10 | import 'package:wow_english/route/route.dart'; | 11 | import 'package:wow_english/route/route.dart'; |
| 11 | 12 | ||
| 12 | class App extends StatelessWidget { | 13 | class App extends StatelessWidget { |
| 13 | - const App({super.key}); | 14 | + const App([this._navigatorObserver]); |
| 15 | + | ||
| 16 | + final NavigatorObserver? _navigatorObserver; | ||
| 14 | 17 | ||
| 15 | @override | 18 | @override |
| 16 | Widget build(BuildContext context) { | 19 | Widget build(BuildContext context) { |
| @@ -41,6 +44,11 @@ class App extends StatelessWidget { | @@ -41,6 +44,11 @@ class App extends StatelessWidget { | ||
| 41 | initialRoute: AppRouteName.splash, | 44 | initialRoute: AppRouteName.splash, |
| 42 | navigatorKey: AppRouter.navigatorKey, | 45 | navigatorKey: AppRouter.navigatorKey, |
| 43 | onGenerateRoute: AppRouter.generateRoute, | 46 | onGenerateRoute: AppRouter.generateRoute, |
| 47 | + navigatorObservers: <NavigatorObserver>[ | ||
| 48 | + // 带入ApmNavigatorObserver实例用于路由监听 | ||
| 49 | + // 如果不带入SDK监听器将无法获知页面(PV)入栈退栈行为,错误率(Dart异常数/FlutterPV次数)将异常攀升。 | ||
| 50 | + _navigatorObserver ?? ApmNavigatorObserver.singleInstance | ||
| 51 | + ], | ||
| 44 | ), | 52 | ), |
| 45 | )), | 53 | )), |
| 46 | ); | 54 | ); |
lib/common/request/basic_config.dart
| 1 | -import 'package:flutter/cupertino.dart'; | 1 | +import 'package:flutter/foundation.dart'; |
| 2 | 2 | ||
| 3 | class BasicConfig { | 3 | class BasicConfig { |
| 4 | // static bool isTestDev = true; | 4 | // static bool isTestDev = true; |
| @@ -7,7 +7,6 @@ class BasicConfig { | @@ -7,7 +7,6 @@ class BasicConfig { | ||
| 7 | 7 | ||
| 8 | // 暂时未启用 | 8 | // 暂时未启用 |
| 9 | static bool isEnvProd() { | 9 | static bool isEnvProd() { |
| 10 | - bool kReleaseMode = const bool.fromEnvironment('dart.vm.product'); | ||
| 11 | if (kReleaseMode) { | 10 | if (kReleaseMode) { |
| 12 | debugPrint("dart.vm.product-现在是release环境."); | 11 | debugPrint("dart.vm.product-现在是release环境."); |
| 13 | } else { | 12 | } else { |
lib/main.dart
| 1 | import 'dart:io'; | 1 | import 'dart:io'; |
| 2 | 2 | ||
| 3 | +import 'package:flutter/foundation.dart'; | ||
| 3 | import 'package:flutter/material.dart'; | 4 | import 'package:flutter/material.dart'; |
| 4 | import 'package:flutter/services.dart'; | 5 | import 'package:flutter/services.dart'; |
| 6 | +import 'package:package_info_plus/package_info_plus.dart'; | ||
| 7 | +import 'package:umeng_apm_sdk/umeng_apm_sdk.dart'; | ||
| 5 | import 'package:wow_english/app/app.dart'; | 8 | import 'package:wow_english/app/app.dart'; |
| 6 | 9 | ||
| 10 | +// void main() { | ||
| 11 | +// ///设置设备默认方向 | ||
| 12 | +// WidgetsFlutterBinding.ensureInitialized(); | ||
| 13 | +// if (Platform.isAndroid) { | ||
| 14 | +// SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( //设置状态栏透明 | ||
| 15 | +// statusBarColor: Colors.transparent, | ||
| 16 | +// )); | ||
| 17 | +// } | ||
| 18 | +// runApp(const App()); | ||
| 19 | +// } | ||
| 20 | + | ||
| 7 | void main() { | 21 | void main() { |
| 8 | ///设置设备默认方向 | 22 | ///设置设备默认方向 |
| 9 | - WidgetsFlutterBinding.ensureInitialized(); | ||
| 10 | if (Platform.isAndroid) { | 23 | if (Platform.isAndroid) { |
| 11 | SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( //设置状态栏透明 | 24 | SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( //设置状态栏透明 |
| 12 | statusBarColor: Colors.transparent, | 25 | statusBarColor: Colors.transparent, |
| 13 | )); | 26 | )); |
| 14 | } | 27 | } |
| 15 | - runApp(const App()); | 28 | + |
| 29 | + final UmengApmSdk umengApmSdk = UmengApmSdk( | ||
| 30 | + name: "", | ||
| 31 | + bver: "", | ||
| 32 | + | ||
| 33 | + // 是否开启SDK运行时日志输出 | ||
| 34 | + enableLog: !kReleaseMode, | ||
| 35 | + | ||
| 36 | + // 您使用的flutter版本,默认为空,为方便定位访问,建议配置 | ||
| 37 | + flutterVersion: '3.13.2', | ||
| 38 | + | ||
| 39 | + // 您使用的flutter引擎版本 | ||
| 40 | + engineVersion: 'ff5b5b5fa6', | ||
| 41 | + | ||
| 42 | + // 开启监测页面帧率(默认关闭) 版本 v2.1.3 可支持 | ||
| 43 | + enableTrackingPageFps: !kReleaseMode, | ||
| 44 | + | ||
| 45 | + // 开启监测页面性能(默认关闭)版本 v2.1.3 可支持 | ||
| 46 | + enableTrackingPagePerf: !kReleaseMode, | ||
| 47 | + | ||
| 48 | + // 带入继承ApmWidgetsFlutterBinding的覆写和初始化方法, 可用于自定义监听应用生命周期 | ||
| 49 | + // 确保去掉原有的WidgetsFlutterBinding.ensureInitialized() ,以免出现重复初始化绑定的异常造成无法正常初始化,SDK内部已通过initFlutterBinding入参带入继承的WidgetsFlutterBinding实现初始化操作 | ||
| 50 | + initFlutterBinding: MyApmWidgetsFlutterBinding.ensureInitialized, | ||
| 51 | + | ||
| 52 | + // 抛出异常事件 | ||
| 53 | + onError: (exception, stack) { | ||
| 54 | + debugPrint(exception.toString()); | ||
| 55 | + }, | ||
| 56 | + | ||
| 57 | + ); | ||
| 58 | + umengApmSdk.init(appRunner: (observer) async { | ||
| 59 | + // 确保去掉原有的WidgetsFlutterBinding.ensureInitialized() ,以免出现重复初始化绑定的异常造成无法正常初始化,SDK内部已通过initFlutterBinding入参带入继承的WidgetsFlutterBinding实现初始化操作 | ||
| 60 | + // 依赖ensureInitialized()初始化的代码可在此调用 | ||
| 61 | + // 需要异步获取设置应用名称和版本号可在此回调中操作 | ||
| 62 | + // SDK实例化的设置可先将name和bver 为 "",然后通过以下方式进行设置 | ||
| 63 | + PackageInfo packageInfo = await PackageInfo.fromPlatform(); | ||
| 64 | + String packageName = packageInfo.packageName; | ||
| 65 | + String buildNumber = packageInfo.buildNumber; | ||
| 66 | + String version = packageInfo.version; | ||
| 67 | + umengApmSdk.name = packageName; | ||
| 68 | + umengApmSdk.bver = '$version+$buildNumber'; | ||
| 69 | + | ||
| 70 | + return App(observer); | ||
| 71 | + }); | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | + | ||
| 75 | +//ApmWidgetsFlutterBinding的覆写和初始化方法 | ||
| 76 | +class MyApmWidgetsFlutterBinding extends ApmWidgetsFlutterBinding { | ||
| 77 | + @override | ||
| 78 | + void handleAppLifecycleStateChanged(AppLifecycleState state) { | ||
| 79 | + // 添加自己的实现逻辑 | ||
| 80 | + debugPrint('AppLifecycleState changed to $state'); | ||
| 81 | + super.handleAppLifecycleStateChanged(state); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + static WidgetsBinding? ensureInitialized() { | ||
| 85 | + MyApmWidgetsFlutterBinding(); | ||
| 86 | + return WidgetsBinding.instance; | ||
| 87 | + } | ||
| 16 | } | 88 | } |