Merge pull request #24 from kirmanak/flipper
Use Flipper instead of Stetho
This commit is contained in:
@@ -40,7 +40,7 @@ android {
|
|||||||
debug {
|
debug {
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
shrinkResources true
|
shrinkResources true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'proguard-rules-debug.pro'
|
||||||
}
|
}
|
||||||
release {
|
release {
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
@@ -109,7 +109,7 @@ dependencies {
|
|||||||
// https://github.com/square/okhttp/tags
|
// https://github.com/square/okhttp/tags
|
||||||
implementation platform("com.squareup.okhttp3:okhttp-bom:4.9.3")
|
implementation platform("com.squareup.okhttp3:okhttp-bom:4.9.3")
|
||||||
implementation "com.squareup.okhttp3:okhttp"
|
implementation "com.squareup.okhttp3:okhttp"
|
||||||
implementation "com.squareup.okhttp3:logging-interceptor"
|
debugImplementation "com.squareup.okhttp3:logging-interceptor"
|
||||||
testImplementation "com.squareup.okhttp3:mockwebserver"
|
testImplementation "com.squareup.okhttp3:mockwebserver"
|
||||||
|
|
||||||
// https://github.com/Kotlin/kotlinx.serialization/releases
|
// https://github.com/Kotlin/kotlinx.serialization/releases
|
||||||
@@ -155,11 +155,19 @@ dependencies {
|
|||||||
// https://mvnrepository.com/artifact/com.google.truth/truth
|
// https://mvnrepository.com/artifact/com.google.truth/truth
|
||||||
testImplementation "com.google.truth:truth:1.1.3"
|
testImplementation "com.google.truth:truth:1.1.3"
|
||||||
|
|
||||||
// https://github.com/facebook/stetho/releases
|
|
||||||
def stetho_version = "1.6.0"
|
|
||||||
implementation "com.facebook.stetho:stetho:$stetho_version"
|
|
||||||
implementation "com.facebook.stetho:stetho-okhttp3:$stetho_version"
|
|
||||||
|
|
||||||
// https://github.com/androidbroadcast/ViewBindingPropertyDelegate/releases
|
// https://github.com/androidbroadcast/ViewBindingPropertyDelegate/releases
|
||||||
implementation "com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.3"
|
implementation "com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.3"
|
||||||
|
|
||||||
|
// https://github.com/facebook/flipper/releases
|
||||||
|
def flipper_version = "0.127.0"
|
||||||
|
debugImplementation "com.facebook.flipper:flipper:$flipper_version"
|
||||||
|
debugImplementation "com.facebook.flipper:flipper-leakcanary2-plugin:$flipper_version"
|
||||||
|
debugImplementation "com.facebook.flipper:flipper-network-plugin:$flipper_version"
|
||||||
|
|
||||||
|
// https://github.com/facebook/SoLoader/releases
|
||||||
|
debugImplementation "com.facebook.soloader:soloader:0.10.3"
|
||||||
|
|
||||||
|
// https://github.com/square/leakcanary/releases
|
||||||
|
debugImplementation "com.squareup.leakcanary:leakcanary-android:2.7"
|
||||||
|
|
||||||
}
|
}
|
||||||
25
app/proguard-rules-debug.pro
Normal file
25
app/proguard-rules-debug.pro
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
|
### Flipper https://github.com/facebook/flipper/issues/314#issuecomment-940828336 ###
|
||||||
|
-keep class com.facebook.jni.** { *; }
|
||||||
|
-keep class com.facebook.flipper.** { *; }
|
||||||
|
### Flipper https://github.com/facebook/flipper/issues/314#issuecomment-940828336 ###
|
||||||
33
app/src/debug/java/gq/kirmanak/mealient/App.kt
Normal file
33
app/src/debug/java/gq/kirmanak/mealient/App.kt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package gq.kirmanak.mealient
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import com.facebook.flipper.android.AndroidFlipperClient
|
||||||
|
import com.facebook.flipper.android.utils.FlipperUtils
|
||||||
|
import com.facebook.flipper.core.FlipperPlugin
|
||||||
|
import com.facebook.soloader.SoLoader
|
||||||
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltAndroidApp
|
||||||
|
class App : Application() {
|
||||||
|
// Use @JvmSuppressWildcards because otherwise dagger can't inject it (https://stackoverflow.com/a/43149382)
|
||||||
|
@Inject
|
||||||
|
lateinit var flipperPlugins: Set<@JvmSuppressWildcards FlipperPlugin>
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
Timber.plant(Timber.DebugTree())
|
||||||
|
Timber.v("onCreate() called")
|
||||||
|
setupFlipper()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupFlipper() {
|
||||||
|
if (FlipperUtils.shouldEnableFlipper(this)) {
|
||||||
|
SoLoader.init(this, false)
|
||||||
|
val flipperClient = AndroidFlipperClient.getInstance(this)
|
||||||
|
for (flipperPlugin in flipperPlugins) flipperClient.addPlugin(flipperPlugin)
|
||||||
|
flipperClient.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
78
app/src/debug/java/gq/kirmanak/mealient/di/DebugModule.kt
Normal file
78
app/src/debug/java/gq/kirmanak/mealient/di/DebugModule.kt
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package gq.kirmanak.mealient.di
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.facebook.flipper.core.FlipperPlugin
|
||||||
|
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin
|
||||||
|
import com.facebook.flipper.plugins.inspector.DescriptorMapping
|
||||||
|
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin
|
||||||
|
import com.facebook.flipper.plugins.leakcanary2.FlipperLeakListener
|
||||||
|
import com.facebook.flipper.plugins.leakcanary2.LeakCanary2FlipperPlugin
|
||||||
|
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor
|
||||||
|
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin
|
||||||
|
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import dagger.multibindings.IntoSet
|
||||||
|
import leakcanary.LeakCanary
|
||||||
|
import okhttp3.Interceptor
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
object DebugModule {
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@IntoSet
|
||||||
|
fun provideLoggingInterceptor(): Interceptor {
|
||||||
|
val interceptor = HttpLoggingInterceptor { message -> Timber.tag("OkHttp").v(message) }
|
||||||
|
interceptor.level = HttpLoggingInterceptor.Level.BODY
|
||||||
|
return interceptor
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@IntoSet
|
||||||
|
fun provideFlipperInterceptor(networkFlipperPlugin: NetworkFlipperPlugin): Interceptor {
|
||||||
|
return FlipperOkhttpInterceptor(networkFlipperPlugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun networkFlipperPlugin() = NetworkFlipperPlugin()
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@IntoSet
|
||||||
|
fun bindNetworkFlipperPlugin(plugin: NetworkFlipperPlugin): FlipperPlugin = plugin
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@IntoSet
|
||||||
|
fun sharedPreferencesPlugin(@ApplicationContext context: Context): FlipperPlugin =
|
||||||
|
SharedPreferencesFlipperPlugin(context)
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@IntoSet
|
||||||
|
fun leakCanaryPlugin(): FlipperPlugin {
|
||||||
|
LeakCanary.config = LeakCanary.config.copy(onHeapAnalyzedListener = FlipperLeakListener())
|
||||||
|
return LeakCanary2FlipperPlugin()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@IntoSet
|
||||||
|
fun databasesPlugin(@ApplicationContext context: Context): FlipperPlugin =
|
||||||
|
DatabasesFlipperPlugin(context)
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@IntoSet
|
||||||
|
fun inspectorPlugin(@ApplicationContext context: Context): FlipperPlugin =
|
||||||
|
InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())
|
||||||
|
}
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package gq.kirmanak.mealient
|
|
||||||
|
|
||||||
import android.app.Application
|
|
||||||
import com.facebook.stetho.Stetho
|
|
||||||
import dagger.hilt.android.HiltAndroidApp
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
@HiltAndroidApp
|
|
||||||
class App : Application() {
|
|
||||||
override fun onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
if (BuildConfig.DEBUG) {
|
|
||||||
Timber.plant(Timber.DebugTree())
|
|
||||||
Stetho.initializeWithDefaults(this)
|
|
||||||
}
|
|
||||||
Timber.v("onCreate() called")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +1,21 @@
|
|||||||
package gq.kirmanak.mealient.data.impl
|
package gq.kirmanak.mealient.data.impl
|
||||||
|
|
||||||
import com.facebook.stetho.okhttp3.StethoInterceptor
|
|
||||||
import gq.kirmanak.mealient.BuildConfig
|
|
||||||
import gq.kirmanak.mealient.data.auth.impl.AuthOkHttpInterceptor
|
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.logging.HttpLoggingInterceptor
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class OkHttpBuilder @Inject constructor(
|
class OkHttpBuilder
|
||||||
private val authOkHttpInterceptor: AuthOkHttpInterceptor
|
@Inject
|
||||||
|
constructor(
|
||||||
|
// Use @JvmSuppressWildcards because otherwise dagger can't inject it (https://stackoverflow.com/a/43149382)
|
||||||
|
private val interceptors: Set<@JvmSuppressWildcards Interceptor>
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun buildOkHttp(): OkHttpClient {
|
fun buildOkHttp(): OkHttpClient {
|
||||||
Timber.v("buildOkHttp() called")
|
Timber.v("buildOkHttp() called")
|
||||||
val builder = OkHttpClient.Builder()
|
return OkHttpClient.Builder()
|
||||||
builder.addNetworkInterceptor(authOkHttpInterceptor)
|
.apply { for (interceptor in interceptors) addNetworkInterceptor(interceptor) }
|
||||||
if (BuildConfig.DEBUG) {
|
.build()
|
||||||
builder.addNetworkInterceptor(buildLoggingInterceptor())
|
|
||||||
builder.addNetworkInterceptor(StethoInterceptor())
|
|
||||||
}
|
|
||||||
return builder.build()
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun buildLoggingInterceptor(): Interceptor {
|
|
||||||
val interceptor = HttpLoggingInterceptor { message -> Timber.tag("OkHttp").v(message) }
|
|
||||||
interceptor.level = HttpLoggingInterceptor.Level.BODY
|
|
||||||
return interceptor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,26 +4,33 @@ import dagger.Binds
|
|||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import dagger.multibindings.IntoSet
|
||||||
import gq.kirmanak.mealient.data.auth.AuthDataSource
|
import gq.kirmanak.mealient.data.auth.AuthDataSource
|
||||||
import gq.kirmanak.mealient.data.auth.AuthRepo
|
import gq.kirmanak.mealient.data.auth.AuthRepo
|
||||||
import gq.kirmanak.mealient.data.auth.AuthStorage
|
import gq.kirmanak.mealient.data.auth.AuthStorage
|
||||||
import gq.kirmanak.mealient.data.auth.impl.AuthDataSourceImpl
|
import gq.kirmanak.mealient.data.auth.impl.AuthDataSourceImpl
|
||||||
|
import gq.kirmanak.mealient.data.auth.impl.AuthOkHttpInterceptor
|
||||||
import gq.kirmanak.mealient.data.auth.impl.AuthRepoImpl
|
import gq.kirmanak.mealient.data.auth.impl.AuthRepoImpl
|
||||||
import gq.kirmanak.mealient.data.auth.impl.AuthStorageImpl
|
import gq.kirmanak.mealient.data.auth.impl.AuthStorageImpl
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
|
import okhttp3.Interceptor
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
@ExperimentalSerializationApi
|
@ExperimentalSerializationApi
|
||||||
@Module
|
@Module
|
||||||
@InstallIn(SingletonComponent::class)
|
@InstallIn(SingletonComponent::class)
|
||||||
interface AuthModule {
|
interface AuthModule {
|
||||||
@Binds
|
@Binds
|
||||||
fun bindAuthDataSource(authDataSourceImpl: AuthDataSourceImpl): AuthDataSource
|
fun bindAuthDataSource(authDataSourceImpl: AuthDataSourceImpl): AuthDataSource
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
fun bindAuthStorage(authStorageImpl: AuthStorageImpl): AuthStorage
|
fun bindAuthStorage(authStorageImpl: AuthStorageImpl): AuthStorage
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
fun bindAuthRepo(authRepo: AuthRepoImpl): AuthRepo
|
fun bindAuthRepo(authRepo: AuthRepoImpl): AuthRepo
|
||||||
}
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
fun bindAuthInterceptor(authOkHttpInterceptor: AuthOkHttpInterceptor): Interceptor
|
||||||
|
}
|
||||||
|
|||||||
@@ -77,4 +77,11 @@ class RecipesFragment : Fragment(R.layout.fragment_recipes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
Timber.v("onDestroyView() called")
|
||||||
|
// Prevent RV leaking through mObservers list in adapter
|
||||||
|
binding.recipes.adapter = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -51,4 +51,14 @@ class RecipeInfoFragment : BottomSheetDialogFragment() {
|
|||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
|
||||||
BottomSheetDialog(requireContext(), R.style.NoShapeBottomSheetDialog)
|
BottomSheetDialog(requireContext(), R.style.NoShapeBottomSheetDialog)
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
Timber.v("onDestroyView() called")
|
||||||
|
// Prevent RV leaking through mObservers list in adapter
|
||||||
|
with(binding) {
|
||||||
|
ingredientsList.adapter = null
|
||||||
|
instructionsList.adapter = null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
7
app/src/release/java/gq/kirmanak/mealient/App.kt
Normal file
7
app/src/release/java/gq/kirmanak/mealient/App.kt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package gq.kirmanak.mealient
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
|
|
||||||
|
@HiltAndroidApp
|
||||||
|
class App : Application()
|
||||||
Reference in New Issue
Block a user