1import MusicQueue from '@/core/musicQueue'; 2import MusicSheet from '@/core/musicSheet'; 3import {check, PERMISSIONS, request} from 'react-native-permissions'; 4import TrackPlayer, {Capability} from 'react-native-track-player'; 5import 'react-native-get-random-values'; 6import {Platform, ToastAndroid} from 'react-native'; 7import {loadConfig} from '@/core/localConfigManager'; 8import RNBootSplash from 'react-native-bootsplash'; 9import RNFS, {exists, mkdir} from 'react-native-fs'; 10import Download from '@/core/download'; 11import pathConst from '@/constants/pathConst'; 12import {checkAndCreateDir} from '@/utils/fileUtils'; 13import {errorLog} from '@/utils/log'; 14import MediaMeta from '@/core/mediaMeta'; 15import Cache from '@/core/cache'; 16import PluginManager from '@/core/plugin'; 17 18/** app加载前执行 19 * 1. 检查权限 20 * 2. 数据初始化 21 * 3. 22 */ 23async function _bootstrap() { 24 // 检查权限 25 const [readStoragePermission, writeStoragePermission] = await Promise.all([ 26 check(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE), 27 check(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE), 28 ]); 29 if ( 30 !( 31 readStoragePermission === 'granted' && 32 writeStoragePermission === 'granted' 33 ) 34 ) { 35 await request(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE); 36 await request(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE); 37 } 38 39 /** 初始化路径 */ 40 await setupFolder(); 41 // 加载配置 42 await loadConfig(); 43 44 await Cache.setup(); 45 // 加载插件 46 try { 47 await TrackPlayer.setupPlayer(); 48 } catch (e: any) { 49 if ( 50 e?.message !== 'The player has already been initialized via setupPlayer.' 51 ) { 52 throw e; 53 } 54 } 55 56 Promise.all([ 57 58 await MediaMeta.setup(), 59 ]); 60 await TrackPlayer.updateOptions({ 61 progressUpdateEventInterval: 0.4, 62 stopWithApp: false, 63 alwaysPauseOnInterruption: true, 64 capabilities: [ 65 Capability.Play, 66 Capability.Pause, 67 Capability.SkipToNext, 68 Capability.SkipToPrevious, 69 ], 70 compactCapabilities: [ 71 Capability.Play, 72 Capability.Pause, 73 Capability.SkipToNext, 74 Capability.SkipToPrevious, 75 ], 76 notificationCapabilities: [ 77 Capability.Play, 78 Capability.Pause, 79 Capability.SkipToNext, 80 Capability.SkipToPrevious, 81 ], 82 }); 83 await MusicQueue.setup(); 84 await MusicSheet.setup(); 85 await Download.setup(); 86 await PluginManager.setup(); 87 88 89 ErrorUtils.setGlobalHandler(error => { 90 errorLog('未捕获的错误', error); 91 }); 92} 93 94/** 初始化 */ 95async function setupFolder() { 96 await Promise.all([ 97 checkAndCreateDir(pathConst.dataPath), 98 checkAndCreateDir(pathConst.logPath), 99 checkAndCreateDir(pathConst.cachePath), 100 checkAndCreateDir(pathConst.storagePath), 101 checkAndCreateDir(pathConst.pluginPath), 102 checkAndCreateDir(pathConst.lrcCachePath), 103 ]); 104} 105 106export default async function () { 107 try { 108 await _bootstrap(); 109 } catch (e) { 110 errorLog('初始化出错', e); 111 console.log(e); 112 } 113 // 隐藏开屏动画 114 console.log('HIDE'); 115 RNBootSplash.hide({fade: true}); 116} 117