@@ -4,155 +4,98 @@ package com.d4rk.androidtutorials.data.core
44
55import android.annotation.SuppressLint
66import android.app.Activity
7- import android.app.Application
87import android.database.sqlite.SQLiteException
98import android.os.Bundle
109import android.util.Log
1110import androidx.lifecycle.Lifecycle
12- import androidx.lifecycle.LifecycleObserver
1311import androidx.lifecycle.OnLifecycleEvent
1412import androidx.lifecycle.ProcessLifecycleOwner
15- import androidx.multidex.MultiDexApplication
1613import androidx.room.Room
1714import androidx.room.migration.Migration
18- import com.d4rk.android.libs.apptoolkit.data.client.KtorClient
15+ import com.d4rk.android.libs.apptoolkit.data.core.BaseCoreManager
16+ import com.d4rk.android.libs.apptoolkit.data.core.ads.AdsCoreManager
1917import com.d4rk.android.libs.apptoolkit.utils.error.ErrorHandler
2018import com.d4rk.android.libs.apptoolkit.utils.error.ErrorHandler.handleInitializationFailure
21- import com.d4rk.androidtutorials.data.core.ads.AdsCoreManager
22- import com.d4rk.androidtutorials.data.core.datastore.DataStoreCoreManager
2319import com.d4rk.androidtutorials.data.database.AppDatabase
2420import com.d4rk.androidtutorials.data.database.migrations.MIGRATION_1_2
2521import com.d4rk.androidtutorials.data.database.migrations.MIGRATION_2_3
2622import com.d4rk.androidtutorials.data.datastore.DataStore
23+ import com.d4rk.androidtutorials.utils.constants.ads.AdsConstants
2724import com.d4rk.androidtutorials.utils.error.CrashlyticsErrorReporter
2825import io.ktor.client.HttpClient
29- import kotlinx.coroutines.CoroutineScope
3026import kotlinx.coroutines.Deferred
31- import kotlinx.coroutines.Dispatchers
3227import kotlinx.coroutines.async
33- import kotlinx.coroutines.awaitAll
34- import kotlinx.coroutines.coroutineScope
35- import kotlinx.coroutines.launch
3628import kotlinx.coroutines.supervisorScope
3729
38- class AppCoreManager : MultiDexApplication () , Application.ActivityLifecycleCallbacks , LifecycleObserver {
30+ class AppCoreManager : BaseCoreManager () {
3931
40- private val dataStoreCoreManager : DataStoreCoreManager by lazy {
41- DataStoreCoreManager (context = this )
42- }
32+ private var currentActivity : Activity ? = null
4333
44- private val adsCoreManager : AdsCoreManager by lazy {
45- AdsCoreManager (context = this )
46- }
34+ companion object {
35+ @SuppressLint(" StaticFieldLeak" )
36+ lateinit var instance : AppCoreManager
37+ private set
4738
48- private var currentActivity : Activity ? = null
39+ lateinit var dataStore : DataStore
40+ private set
41+
42+ lateinit var database : AppDatabase
43+ private set
44+
45+ val adsCoreManager : AdsCoreManager by lazy {
46+ AdsCoreManager (context = instance)
47+ }
48+
49+ val ktorClient : HttpClient
50+ get() = BaseCoreManager .ktorClient
51+
52+ val isAppLoaded : Boolean
53+ get() = BaseCoreManager .isAppLoaded
54+ }
4955
5056 override fun onCreate () {
5157 super .onCreate()
5258 instance = this
53- registerActivityLifecycleCallbacks(this )
5459
5560 val crashlyticsReporter = CrashlyticsErrorReporter ()
5661 ErrorHandler .init (reporter = crashlyticsReporter)
5762
63+ registerActivityLifecycleCallbacks(this )
5864 ProcessLifecycleOwner .get().lifecycle.addObserver(observer = this )
59- CoroutineScope (context = Dispatchers .IO ).launch {
60- initializeApp()
61- }
6265 }
6366
64- private suspend fun initializeApp () = supervisorScope {
65- val ktor : Deferred <Unit > = async { initializeKtorClient() }
66- val dataBase : Deferred <Unit > = async { initializeDatabase() }
67- val dataStore : Deferred <Unit > = async { initializeDataStore() }
68-
69- ktor.await()
70- dataBase.await()
71- dataStore.await()
72-
73- adsCoreManager.initializeAds()
67+ override suspend fun onInitializeApp () = supervisorScope {
68+ val dataStoreInitialization : Deferred <Unit > = async { initializeDataStore() }
69+ val databaseInitialization : Deferred <Unit > = async { initializeDatabase() }
70+ val adsInitialization : Deferred <Unit > = async { initializeAds() }
7471
75- initializeAds()
76- finalizeInitialization()
72+ dataStoreInitialization.await()
73+ databaseInitialization.await()
74+ adsInitialization.await()
7775 }
7876
79- private suspend fun initializeKtorClient () {
77+ private fun initializeDataStore () {
8078 runCatching {
81- coroutineScope {
82- val tasks : List <Deferred <Unit >> =
83- listOf (element = async(context = Dispatchers .IO ) {
84- ktorClient = KtorClient ().createClient()
85- })
86- tasks.awaitAll()
87- }
79+ dataStore = DataStore .getInstance(context = this @AppCoreManager)
8880 }.onFailure {
8981 handleInitializationFailure(
90- message = " Ktor client initialization failed" ,
91- exception = it as Exception ,
92- applicationContext = applicationContext
82+ message = " DataStore initialization failed" , exception = it as Exception , applicationContext = applicationContext
9383 )
9484 }
9585 }
9686
9787 private suspend fun initializeDatabase () {
9888 runCatching {
9989 database = Room .databaseBuilder(
100- context = this @AppCoreManager,
101- klass = AppDatabase ::class .java,
102- name = " Android Studio Tutorials"
103- )
104- .addMigrations(migrations = getMigrations())
105- .fallbackToDestructiveMigration()
106- .fallbackToDestructiveMigrationOnDowngrade()
107- .build()
90+ context = this @AppCoreManager , klass = AppDatabase ::class .java , name = " Android Studio Tutorials"
91+ ).addMigrations(migrations = getMigrations()).fallbackToDestructiveMigration().fallbackToDestructiveMigrationOnDowngrade().build()
10892
10993 database.openHelper.writableDatabase
11094 }.onFailure {
11195 handleDatabaseError(exception = it as Exception )
11296 }
11397 }
11498
115- private fun getMigrations () : Array <Migration > {
116- return arrayOf(
117- MIGRATION_1_2 ,
118- MIGRATION_2_3 ,
119- )
120- }
121-
122- private suspend fun initializeDataStore () {
123- runCatching {
124- dataStore = DataStore .getInstance(context = this @AppCoreManager)
125- dataStoreCoreManager.initializeDataStore()
126- }.onFailure {
127- handleInitializationFailure(
128- message = " DataStore initialization failed" ,
129- exception = it as Exception ,
130- applicationContext = applicationContext
131- )
132- }
133- }
134-
135- private fun initializeAds () {
136- runCatching {
137- adsCoreManager.initializeAds()
138- }.onFailure {
139- handleInitializationFailure(
140- message = " Ads initialization failed" ,
141- exception = it as Exception ,
142- applicationContext = applicationContext
143- )
144- }
145- }
146-
147- private fun finalizeInitialization () {
148- markAppAsLoaded()
149- }
150-
151- @OnLifecycleEvent(Lifecycle .Event .ON_START )
152- fun onMoveToForeground () {
153- currentActivity?.let { adsCoreManager.showAdIfAvailable(activity = it) }
154- }
155-
15699 private suspend fun handleDatabaseError (exception : Exception ) {
157100 if (exception is SQLiteException || (exception is IllegalStateException && exception.message?.contains(other = " Migration failed" ) == true )) {
158101 eraseDatabase()
@@ -173,44 +116,34 @@ class AppCoreManager : MultiDexApplication() , Application.ActivityLifecycleCall
173116 Log .e(" AppCoreManager" , " Database error: ${exception.message} " , exception)
174117 }
175118
176- private fun markAppAsLoaded () {
177- isAppLoaded = true
119+ private fun initializeAds () {
120+ adsCoreManager.initializeAds(AdsConstants .APP_OPEN_UNIT_ID )
121+ }
122+
123+ private fun getMigrations () : Array <Migration > {
124+ return arrayOf(
125+ MIGRATION_1_2 , MIGRATION_2_3
126+ )
178127 }
179128
180129 fun isAppLoaded () : Boolean {
181130 return isAppLoaded
182131 }
183132
133+ @OnLifecycleEvent(Lifecycle .Event .ON_START )
134+ fun onMoveToForeground () {
135+ currentActivity?.let { adsCoreManager.showAdIfAvailable(it) }
136+ }
137+
184138 override fun onActivityCreated (activity : Activity , savedInstanceState : Bundle ? ) {}
185139
186140 override fun onActivityStarted (activity : Activity ) {
187- if (! adsCoreManager.isShowingAd) {
188- currentActivity = activity
189- }
141+ currentActivity = activity
190142 }
191143
192144 override fun onActivityResumed (activity : Activity ) {}
193145 override fun onActivityPaused (activity : Activity ) {}
194146 override fun onActivityStopped (activity : Activity ) {}
195147 override fun onActivitySaveInstanceState (activity : Activity , outState : Bundle ) {}
196148 override fun onActivityDestroyed (activity : Activity ) {}
197-
198- companion object {
199-
200- lateinit var dataStore : DataStore
201- private set
202-
203- lateinit var database : AppDatabase
204- private set
205-
206- @SuppressLint(" StaticFieldLeak" )
207- lateinit var instance : AppCoreManager
208- private set
209-
210- lateinit var ktorClient : HttpClient
211- private set
212-
213- var isAppLoaded : Boolean = false
214- private set
215- }
216149}
0 commit comments