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 Config from '@/core/config'; 7import RNBootSplash from 'react-native-bootsplash'; 8import pathConst from '@/constants/pathConst'; 9import {checkAndCreateDir} from '@/utils/fileUtils'; 10import {errorLog, trace} from '@/utils/log'; 11import MediaMeta from '@/core/mediaMeta'; 12import Cache from '@/core/cache'; 13import PluginManager from '@/core/pluginManager'; 14import Network from '@/core/network'; 15import {ImgAsset} from '@/constants/assetsConst'; 16import LocalMusicSheet from '@/core/localMusicSheet'; 17import {StatusBar} from 'react-native'; 18import Theme from '@/core/theme'; 19import LyricManager from '@/core/lyricManager'; 20import {getStorage, setStorage} from '@/utils/storage'; 21 22/** app加载前执行 23 * 1. 检查权限 24 * 2. 数据初始化 25 * 3. 26 */ 27async function _bootstrap() { 28 // 1. 检查权限 29 const [readStoragePermission, writeStoragePermission] = await Promise.all([ 30 check(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE), 31 check(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE), 32 ]); 33 if ( 34 !( 35 readStoragePermission === 'granted' && 36 writeStoragePermission === 'granted' 37 ) 38 ) { 39 await request(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE); 40 await request(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE); 41 } 42 43 // 2. 数据初始化 44 /** 初始化路径 */ 45 await setupFolder(); 46 trace('文件夹初始化完成'); 47 // 加载配置 48 await Promise.all([ 49 Config.setup(), 50 MediaMeta.setup(), 51 MusicSheet.setup(), 52 Network.setup(), 53 ]); 54 trace('配置初始化完成'); 55 // 加载插件 56 try { 57 await TrackPlayer.setupPlayer({ 58 maxCacheSize: 59 Config.get('setting.basic.maxCacheSize') ?? 1024 * 1024 * 512, 60 }); 61 } catch (e: any) { 62 if ( 63 e?.message !== 64 'The player has already been initialized via setupPlayer.' 65 ) { 66 throw e; 67 } 68 } 69 await TrackPlayer.updateOptions({ 70 icon: ImgAsset.logoTransparent, 71 alwaysPauseOnInterruption: true, 72 progressUpdateEventInterval: 1, 73 capabilities: [ 74 Capability.Play, 75 Capability.Pause, 76 Capability.SkipToNext, 77 Capability.SkipToPrevious, 78 ], 79 compactCapabilities: [ 80 Capability.Play, 81 Capability.Pause, 82 Capability.SkipToNext, 83 Capability.SkipToPrevious, 84 ], 85 notificationCapabilities: [ 86 Capability.Play, 87 Capability.Pause, 88 Capability.SkipToNext, 89 Capability.SkipToPrevious, 90 ], 91 }); 92 trace('播放器初始化完成'); 93 await Cache.setup(); 94 trace('缓存初始化完成'); 95 await PluginManager.setup(); 96 trace('插件初始化完成'); 97 await MusicQueue.setup(); 98 trace('播放列表初始化完成'); 99 await LocalMusicSheet.setup(); 100 trace('本地音乐初始化完成'); 101 Theme.setup(); 102 trace('主题初始化完成'); 103 await LyricManager.setup(); 104 105 StatusBar.setBackgroundColor('transparent'); 106 StatusBar.setTranslucent(true); 107 // Linking.addEventListener('url', (data) => { 108 // console.log(data); 109 // }) 110 111 extraMakeup(); 112 ErrorUtils.setGlobalHandler(error => { 113 errorLog('未捕获的错误', error); 114 }); 115} 116 117/** 初始化 */ 118async function setupFolder() { 119 await Promise.all([ 120 checkAndCreateDir(pathConst.dataPath), 121 checkAndCreateDir(pathConst.logPath), 122 checkAndCreateDir(pathConst.cachePath), 123 checkAndCreateDir(pathConst.pluginPath), 124 checkAndCreateDir(pathConst.lrcCachePath), 125 checkAndCreateDir(pathConst.downloadPath).then(() => { 126 checkAndCreateDir(pathConst.downloadMusicPath); 127 }), 128 ]); 129} 130 131export default async function () { 132 try { 133 await _bootstrap(); 134 } catch (e) { 135 errorLog('初始化出错', e); 136 } 137 // 隐藏开屏动画 138 console.log('HIDE'); 139 RNBootSplash.hide({fade: true}); 140} 141 142/** 不需要阻塞的 */ 143async function extraMakeup() { 144 try { 145 if (Config.get('setting.basic.autoUpdatePlugin')) { 146 const lastUpdated = 147 (await getStorage('pluginLastupdatedTime')) || 0; 148 const now = Date.now(); 149 if (Math.abs(now - lastUpdated) > 86400000) { 150 setStorage('pluginLastupdatedTime', now); 151 const plugins = PluginManager.getValidPlugins(); 152 for (let i = 0; i < plugins.length; ++i) { 153 const srcUrl = plugins[i].instance.srcUrl; 154 if (srcUrl) { 155 await PluginManager.installPluginFromUrl(srcUrl); 156 } 157 } 158 } 159 } 160 } catch {} 161} 162