A/B testing library for Java/Kotlin/Android
fo2rist/garmin-vehicle-keyfob 3
Garmin app that allow to Lock/Unlock a car from watch
fo2rist/android-drawable-scale-test 1
Test how Android scales drawables for different resolutions
fo2rist/apiai-python-webhook 1
Test webhook for AI API slack-bot
fo2rist/droidcon-kotlin-scope-extension-functions 1
Demo repository with example of good and bad scope functions usage
fo2rist/livejournal-archiver 1
Archives posts from LiveJournal account to local storage
Slack app that prevents no topic conversations
Set of tests that reveal how different dagger dependencies are resolved
fo2rist/formula-history-mobile 0
Formula 1 History & Stats for mobile
startedAppTelemetry/SwiftClient
started time in a day
pull request commentgoogle/iosched
@manuelvicnt Thank you for taking valuable time on this, those are really great findings and should give insights to developers in tests! I also played around a bit with Startup but unfortunately kept getting errors. Hope @tikurahul will rescue us 🤞
comment created time in 2 days
pull request commentgoogle/iosched
Hi @nuhkoca ! Tried locally and yes, the tests keep failing but for a different reason now. EarlyEntryPoints fixes the problem when accessing the graph in tests.
As initializers run automatically, by the time AnalyticsHelperInitializer run and tries to access the context, there's no context because the test hasn't even started yet. And that throws the following runtime exception.
androidx.startup.StartupException: java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.
I thought about removing the automatic initialization for tests and then activating them manually in MainTestApplication, but I couldn't get it to work. Following the [App Startup documentation], I added a new AndroidManifest.xml file in the androidTest folder and added:
<application>
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="remove"/>
</application>
But that does NOT work either! Because ${applicationId} = com.google.samples.apps.iosched.test and the authority in the main app is com.google.samples.apps.iosched. And if you try to hardcode com.google.samples.apps.iosched in there doesn't work as the provider is not the same. It gives a The application could not be installed: INSTALL_FAILED_CONFLICTING_PROVIDER compilation error.
@tikurahul can you help here? Not wanting to run initializers during integration tests seems to be a common use case the community can face.
comment created time in 2 days
pull request commentgoogle/iosched
Let me take a look tomorrow. No need to push your changes with EarlyEntryPoint though :D
comment created time in 3 days
Pull request review commentgoogle/iosched
+/*+ * Copyright 2021 Google LLC+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * https://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++package com.google.samples.apps.iosched.util.initializers++import android.content.Context+import androidx.startup.Initializer+import com.google.samples.apps.iosched.di.InitializerEntryPoint+import com.google.samples.apps.iosched.shared.analytics.AnalyticsHelper+import javax.inject.Inject++class AnalyticsHelperInitializer : Initializer<Unit> {++ @Inject+ lateinit var analyticsHelper: AnalyticsHelper++ override fun create(context: Context) {+ InitializerEntryPoint.resolve(context).inject(this)
Yeah, sorry, meant analyticsHelper = InitializerEntryPoint.resolve(context). analyticsHelper() instead
comment created time in 3 days
Pull request review commentgoogle/iosched
+/*+ * Copyright 2021 Google LLC+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * https://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++package com.google.samples.apps.iosched.di++import android.content.Context+import com.google.samples.apps.iosched.util.initializers.AnalyticsHelperInitializer+import dagger.hilt.EntryPoint+import dagger.hilt.InstallIn+import dagger.hilt.android.EntryPointAccessors+import dagger.hilt.components.SingletonComponent++@EntryPoint+@InstallIn(SingletonComponent::class)+interface InitializerEntryPoint {++ companion object {+ fun resolve(context: Context): InitializerEntryPoint {+ return EntryPointAccessors.fromApplication(+ context,+ InitializerEntryPoint::class.java+ )+ }+ }++ fun inject(initializer: AnalyticsHelperInitializer)
Yes, sorry! I meant to say analyticsHelper instead :) thank you!
comment created time in 3 days
pull request commentgoogle/iosched
@manuelvicnt Thanks a lot for your review. I did the same what you and documentation mentioned but tests still fail. So I need your help here :D Shall I push changes?
comment created time in 3 days
Pull request review commentgoogle/iosched
+/*+ * Copyright 2021 Google LLC+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * https://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++package com.google.samples.apps.iosched.util.initializers++import android.content.Context+import androidx.startup.Initializer+import com.google.samples.apps.iosched.di.InitializerEntryPoint+import com.google.samples.apps.iosched.shared.analytics.AnalyticsHelper+import javax.inject.Inject++class AnalyticsHelperInitializer : Initializer<Unit> {++ @Inject+ lateinit var analyticsHelper: AnalyticsHelper++ override fun create(context: Context) {+ InitializerEntryPoint.resolve(context).inject(this)
Sorry, I didn't get this, why EntryPoint returns initializer instance instead of dependency which is AnalyticsHelper in this class?
comment created time in 3 days
Pull request review commentgoogle/iosched
+/*+ * Copyright 2021 Google LLC+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * https://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++package com.google.samples.apps.iosched.di++import android.content.Context+import com.google.samples.apps.iosched.util.initializers.AnalyticsHelperInitializer+import dagger.hilt.EntryPoint+import dagger.hilt.InstallIn+import dagger.hilt.android.EntryPointAccessors+import dagger.hilt.components.SingletonComponent++@EntryPoint+@InstallIn(SingletonComponent::class)+interface InitializerEntryPoint {++ companion object {+ fun resolve(context: Context): InitializerEntryPoint {+ return EntryPointAccessors.fromApplication(+ context,+ InitializerEntryPoint::class.java+ )+ }+ }++ fun inject(initializer: AnalyticsHelperInitializer)
I think analyticsHelperInitializer should be analyticsHelper instead, right? Cause we have an instance of AnalyticsHelper from the graph.
comment created time in 3 days
pull request commentgoogle/iosched
Hi @nuhkoca ! The problem with the tests are due to EntryPoints being used. In tests, Hilt's SingletonComponent is scoped to the lifetime of the test case instead of the lifetime of the Application.
To get this fixed, you need to use @EarlyEntryPoints instead of @EntryPoints in the different initializers.
More info here: https://dagger.dev/hilt/early-entry-point.html
Let me know if you need more help :D thank you!
comment created time in 3 days
Pull request review commentgoogle/iosched
+/*+ * Copyright 2021 Google LLC+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * https://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++package com.google.samples.apps.iosched.util.initializers++import android.content.Context+import androidx.startup.Initializer+import com.google.samples.apps.iosched.di.InitializerEntryPoint+import com.google.samples.apps.iosched.shared.analytics.AnalyticsHelper+import javax.inject.Inject++class AnalyticsHelperInitializer : Initializer<Unit> {++ @Inject+ lateinit var analyticsHelper: AnalyticsHelper++ override fun create(context: Context) {+ InitializerEntryPoint.resolve(context).inject(this)
analyticsHelperInitializer = InitializerEntryPoint.resolve(context). analyticsHelperInitializer()
As commented above, I'd rather not have entry points behave like Dagger components. Also, the @Inject from analyticsHelper can be removed and can be made private.
Thanks!
comment created time in 3 days
Pull request review commentgoogle/iosched
+/*+ * Copyright 2021 Google LLC+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * https://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++package com.google.samples.apps.iosched.di++import android.content.Context+import com.google.samples.apps.iosched.util.initializers.AnalyticsHelperInitializer+import dagger.hilt.EntryPoint+import dagger.hilt.InstallIn+import dagger.hilt.android.EntryPointAccessors+import dagger.hilt.components.SingletonComponent++@EntryPoint+@InstallIn(SingletonComponent::class)+interface InitializerEntryPoint {++ companion object {+ fun resolve(context: Context): InitializerEntryPoint {+ return EntryPointAccessors.fromApplication(+ context,+ InitializerEntryPoint::class.java+ )+ }+ }++ fun inject(initializer: AnalyticsHelperInitializer)
fun analyticsHelperInitializer(): AnalyticsHelperInitializer
I understand this works as you expect and is nice to read. However, an entry point's responsibility is not injecting classes, entry points expose instances from the graph.
comment created time in 3 days
pull request commentgoogle/iosched
@JoseAlcerreca can you help me for UI tests? After moving AnalyticsHelper out of application and inject it in the Initializer class, UI tests have start to fail and I don't know how to get it to working with Hilt.
comment created time in 3 days
Pull request review commentgoogle/iosched
dependencies { implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) implementation(Libs.CORE_KTX)+ implementation(Libs.APP_STARTUP)
Right of course!
comment created time in 3 days
Pull request review commentgoogle/iosched
import javax.inject.Inject class MainApplication : Application() { // Even if the var isn't used, needs to be initialized at application startup.- @Inject lateinit var analyticsHelper: AnalyticsHelper-- override fun onCreate() {- // ThreeTenBP for times and dates, called before super to be available for objects- AndroidThreeTen.init(this)-- // Enable strict mode before Dagger creates graph- if (BuildConfig.DEBUG) {- enableStrictMode()- }- super.onCreate()-- if (BuildConfig.DEBUG) {- Timber.plant(Timber.DebugTree())- } else {- Timber.plant(CrashlyticsTree())- }- }-- private fun enableStrictMode() {- StrictMode.setThreadPolicy(- Builder()- .detectDiskReads()- .detectDiskWrites()- .detectNetwork()- .penaltyLog()- .build()- )- }+ @Inject+ lateinit var analyticsHelper: AnalyticsHelper
Sure let me blend AppStartup with Hilt :)
comment created time in 6 days
Pull request review commentgoogle/iosched
dependencies { implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) implementation(Libs.CORE_KTX)+ implementation(Libs.APP_STARTUP)
Hmm won't it fail in release app? Please note this is not Startup Macrobenchmark library. I believe, we need AppStartup for release variant, as well, no?
comment created time in 6 days
Pull request review commentgoogle/iosched
</activity> <activity- android:name=".ui.MainActivity" />+ android:name=".ui.MainActivity" >+ <intent-filter>+ <action android:name="com.google.samples.apps.iosched.STARTUP_ACTIVITY" />
This is not related to AppStartup rather Startup Macrobenchmark library. So I measured MainActivity.
comment created time in 6 days
Pull request review commentgoogle/iosched
import javax.inject.Inject class MainApplication : Application() { // Even if the var isn't used, needs to be initialized at application startup.- @Inject lateinit var analyticsHelper: AnalyticsHelper-- override fun onCreate() {- // ThreeTenBP for times and dates, called before super to be available for objects- AndroidThreeTen.init(this)-- // Enable strict mode before Dagger creates graph- if (BuildConfig.DEBUG) {- enableStrictMode()- }- super.onCreate()-- if (BuildConfig.DEBUG) {- Timber.plant(Timber.DebugTree())- } else {- Timber.plant(CrashlyticsTree())- }- }-- private fun enableStrictMode() {- StrictMode.setThreadPolicy(- Builder()- .detectDiskReads()- .detectDiskWrites()- .detectNetwork()- .penaltyLog()- .build()- )- }+ @Inject+ lateinit var analyticsHelper: AnalyticsHelper
Can this have its own initializer?
comment created time in 6 days
Pull request review commentgoogle/iosched
dependencies { implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) implementation(Libs.CORE_KTX)+ implementation(Libs.APP_STARTUP)
can this be debugImplementation?
comment created time in 6 days
Pull request review commentgoogle/iosched
</activity> <activity- android:name=".ui.MainActivity" />+ android:name=".ui.MainActivity" >+ <intent-filter>+ <action android:name="com.google.samples.apps.iosched.STARTUP_ACTIVITY" />
I have 0 experience with AppStartup, but, can this be applied to the LauncherActivity to take its performance loss into account?
comment created time in 6 days
push eventcljla/code
commit sha d5117d2cb5a2dabe0fe9fc8c1c5b59fdfc50c271
Update README for June 2021
push time in 9 days
push eventcljla/code
commit sha d5117d2cb5a2dabe0fe9fc8c1c5b59fdfc50c271
Update README for June 2021
push time in 9 days
pull request commentgoogle/iosched
cc @JoseAlcerreca I think this can be merged, right?
comment created time in 10 days
push eventcljla/code
commit sha 88feee42c0f1fe7d6d295994d85e90c01e57e85e
June works!
push time in 10 days
push eventcljla/code
commit sha 1c9caff70f87e6128804ce7deca4df0d8a5f5aa6
Prepare for June 2021
push time in 10 days
Pull request review commentgoogle/iosched
androidComponents { } dependencies {- //noinspection GradleDependency- implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.0"- implementation 'androidx.test.ext:junit:1.1.2'- implementation 'androidx.test.espresso:espresso-core:3.3.0'- implementation 'androidx.test.uiautomator:uiautomator:2.2.0'- implementation 'androidx.benchmark:benchmark-macro-junit4:1.1.0-SNAPSHOT'+ api platform(project(":depconstraints"))
To be consistent with other modules, moved all dependencies to depconstraints module.
comment created time in 10 days