I have identified a potential problem with Koin Android Compose. I am still searching for a solution on the internet, but I haven't found one yet. The main issue occurs when I create a new resource with certain permissions. At the start, the app crashes immediately. The permission needs to be requested just before the creation of the resource. Since I'm using this resource (RecordRepository) in the MainActivity as the starting point, the permission request cannot be handled due to the crash.
Below, you will find a snippet of the code where the main problem is the creation of the MediaRecorder. Additionally, if the permission is allowed from the settings page, the application will work with no problems.
A partial solution to this problem is to start the application and use the MediaRecorder in another activity, let's call it ActivityB. Therefore, from ActivityA, I will need to request the permission android.permission.RECORD_AUDIO, and only if it is allowed, move on to ActivityB to create the resource. Unfortunately, I do not want to work with this workaround. I want all actions to be in ActivityA
As for the versions of Koin and Compose used, here is a list of all dependencies.
interface RecordRepository {
fun startRecording()
}
RecordRepositoryImp information
class RecordRepositoryImp(
private val mediaRecorder: MediaRecorder
) : RecordRepository {
@Synchronized
override fun startRecording() {
mediaRecorder.prepare()
mediaRecorder.start()
}
@Synchronized
private fun stopRecording() {
mediaRecorder.stop()
mediaRecorder.reset()
mediaRecorder.release()
}
}
AppModule
val appModule = module {
single {
MediaRecorder().apply {
setAudioSource(MediaRecorder.AudioSource.MIC)
setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB)
}
}
single<RecordRepository> {
RecordRepositoryImp(get())
}
Error twon by the Android Studio
FATAL EXCEPTION: main
Process: com.example.rectoolcomposefinal, PID: 30149
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:503)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for '[Factory:'com.example.rectoolcomposefinal.viewModel.RecordViewModel']'
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:58)
at org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:38)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:116)
at org.koin.core.scope.Scope.resolveValue(Scope.kt:246)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:231)
at org.koin.core.scope.Scope.get(Scope.kt:210)
at org.koin.androidx.viewmodel.factory.KoinViewModelFactory.create(KoinViewModelFactory.kt:25)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:153)
at org.koin.androidx.viewmodel.GetViewModelKt.resolveViewModel(GetViewModel.kt:44)
at com.example.rectoolcomposefinal.view.screen.RecordScreenKt.RecordScreen(RecordScreen.kt:80)
at com.example.rectoolcomposefinal.view.activity.ComposableSingletons$MainActivityKt$lambda-1$1.invoke(MainActivity.kt:49)
at com.example.rectoolcomposefinal.view.activity.ComposableSingletons$MainActivityKt$lambda-1$1.invoke(MainActivity.kt:47)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:129)
at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:113)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.material3.SurfaceKt.Surface-T9BRK9s(Surface.kt:110)
at com.example.rectoolcomposefinal.view.activity.ComposableSingletons$MainActivityKt$lambda-2$1.invoke(MainActivity.kt:44)
at com.example.rectoolcomposefinal.view.activity.ComposableSingletons$MainActivityKt$lambda-2$1.invoke(MainActivity.kt:41)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.material3.TextKt.ProvideTextStyle(Text.kt:261)
at androidx.compose.material3.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:81)
at androidx.compose.material3.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:80)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.material3.MaterialThemeKt.MaterialTheme(MaterialTheme.kt:73)
at com.example.rectoolcomposefinal.ui.theme.ThemeKt.RecToolComposeFinalTheme(Theme.kt:65)
at com.example.rectoolcomposefinal.view.activity.ComposableSingletons$MainActivityKt$lambda-3$1.invoke(MainActivity.kt:41)
at com.example.rectoolcomposefinal.view.activity.ComposableSingletons$MainActivityKt$lambda-3$1.invoke(MainActivity.kt:40)
17:51:33.621 E at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.ui.platform.ComposeView.Content(ComposeView.android.kt:428)
at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:252)
at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:251)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.CompositionLocalsKt.ProvideCommonCompositionLocals(CompositionLocals.kt:194)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:123)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:122)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt.ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:114)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$2.invoke(Wrapper.android.kt:156)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$2.invoke(Wrapper.android.kt:155)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:155)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:140)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:78)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3352)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3342)
at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3342)
at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3277)
at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:587)
at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:966)
at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:519)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:140)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(AndroidComposeView.android.kt:1099)
at androidx.compose.ui.platform.WrappedComposition.setContent(Wrapper.android.kt:131)
at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Wrapper.android.kt:181)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.kt:314)
17:51:33.622 E at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.kt:192)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:138)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(AndroidComposeView.android.kt:1174)
at android.view.View.dispatchAttachedToWindow(View.java:18347)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3397)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3404)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3404)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3404)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3404)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1761)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1460)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7183)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
at android.view.Choreographer.doCallbacks(Choreographer.java:761)
at android.view.Choreographer.doFrame(Choreographer.java:696)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
... 3 more
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for '[Singleton:'com.example.rectoolcomposefinal.repository.repo.RecordRepository']'
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:58)
at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:46)
at org.koin.core.instance.SingleInstanceFactory$get$1.invoke(SingleInstanceFactory.kt:53)
at org.koin.core.instance.SingleInstanceFactory$get$1.invoke(SingleInstanceFactory.kt:51)
at org.koin.mp.KoinPlatformTools.synchronized(KoinPlatformTools.kt:20)
at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:51)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:116)
at org.koin.core.scope.Scope.resolveValue(Scope.kt:246)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:231)
at org.koin.core.scope.Scope.get(Scope.kt:210)
at com.example.rectoolcomposefinal.app.AppModuleKt$appModule$1$invoke$$inlined$viewModelOf$default$1.invoke(ViewModelOf.kt:231)
at com.example.rectoolcomposefinal.app.AppModuleKt$appModule$1$invoke$$inlined$viewModelOf$default$1.invoke(ViewModelOf.kt:56)
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:51)
... 99 more
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for '[Singleton:'android.media.MediaRecorder']'
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:58)
at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:46)
at org.koin.core.instance.SingleInstanceFactory$get$1.invoke(SingleInstanceFactory.kt:53)
at org.koin.core.instance.SingleInstanceFactory$get$1.invoke(SingleInstanceFactory.kt:51)
at org.koin.mp.KoinPlatformTools.synchronized(KoinPlatformTools.kt:20)
at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:51)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:116)
at org.koin.core.scope.Scope.resolveValue(Scope.kt:246)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:231)
at org.koin.core.scope.Scope.get(Scope.kt:210)
at com.example.rectoolcomposefinal.app.AppModuleKt$appModule$1$7.invoke(AppModule.kt:78)
at com.example.rectoolcomposefinal.app.AppModuleKt$appModule$1$7.invoke(AppModule.kt:58)
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:51)
... 111 more
17:51:33.622 E Caused by: java.lang.RuntimeException: setAudioSource failed.
at android.media.MediaRecorder.setAudioSource(Native Method)
at com.example.rectoolcomposefinal.app.AppModuleKt$appModule$1$1.invoke(AppModule.kt:30)
at com.example.rectoolcomposefinal.app.AppModuleKt$appModule$1$1.invoke(AppModule.kt:28)
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:51)
... 123 more
I have identified a potential problem with Koin Android Compose. I am still searching for a solution on the internet, but I haven't found one yet. The main issue occurs when I create a new resource with certain permissions. At the start, the app crashes immediately. The permission needs to be requested just before the creation of the resource. Since I'm using this resource (RecordRepository) in the MainActivity as the starting point, the permission request cannot be handled due to the crash.
Below, you will find a snippet of the code where the main problem is the creation of the MediaRecorder. Additionally, if the permission is allowed from the settings page, the application will work with no problems.
A partial solution to this problem is to start the application and use the MediaRecorder in another activity, let's call it
ActivityB
. Therefore, fromActivityA
, I will need to request the permissionandroid.permission.RECORD_AUDIO
, and only if it is allowed, move on to ActivityB to create the resource. Unfortunately, I do not want to work with this workaround. I want all actions to be inActivityA
As for the versions of Koin and Compose used, here is a list of all dependencies.
RecordRepository information
RecordRepositoryImp information
AppModule
Error twon by the Android Studio