0

I have two classes. First is MainActivity.kt, where I have a some string. Second is a ServiceBuilder.kt like this

object ServiceBuilder {

    
    private const val URL = "https://someLink.com" // <------------- In here I should transfer the string in my MainActivity.kt class

    // Create Logger
    private val logger = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)

    // Create a Custom Interceptor to apply Headers application wide
    val headerInterceptor = object: Interceptor {

        override fun intercept(chain: Interceptor.Chain): Response {

            var request = chain.request()

            request = request.newBuilder()
                .addHeader("x-device-type", Build.DEVICE)
                .addHeader("Accept-Language", Locale.getDefault().language)
                .build()

            val response = chain.proceed(request)
            return response
        }
    }

    // Create OkHttp Client
    private val okHttp = OkHttpClient.Builder()
                                        .callTimeout(5, TimeUnit.SECONDS)
                                        .addInterceptor(headerInterceptor)
                                        .addInterceptor(logger)

    // Create Retrofit Builder
    private val builder = Retrofit.Builder().baseUrl(URL)
                                        .addConverterFactory(GsonConverterFactory.create())
                                        .client(okHttp.build())

    // Create Retrofit Instance
    private val retrofit = builder.build()

    fun <T> buildService(serviceType: Class<T>): T {
        return retrofit.create(serviceType)
    }
}

I need rightly transfer string from MainActivity to this object. I think creating MainActivity object inside ServiceBuilder is't good idea, because it allocate a superfluous memory. Using database or SharedPreferences is't good idea too, because this calls will slow down working program and this technologies was created for solving other problems.

Please tell my right way to solving this problem P.S. I now then this question is easy, but I don't now how to design app architecture

Vando
  • 11
  • 2

2 Answers2

0

Yes, you are right. Placing MainActivity object inside ServiceBuilder is not a good idea. Instead, you can add such private field and function to initiate it to ServiceBuilder as a step of service building. Then you will be able to use it in buildService function

private var stringField: String? = null

fun fieldString(stringField: String): ServiceBuilder {
    this.stringField = stringField
    return this
}

And then use it from your activity as

    ServiceBuilder
        .fieldString("string to set")
        .buildService(...)

Also, you can review different moments regarding builder pattern in Kotlin here How to implement Builder pattern in Kotlin?

Vlad L.
  • 154
  • 1
  • 9
  • Thanks for you reply. It's so interesting way. But I don't understand why it no working. When I create the instance ` val destinationService = ServiceBuilder .loadUrl("http://google.com") .buildService(DestinationService::class.java) ` the ` loadUrl("http://google.com") ` I can not replace default link. ` var url = "http://no-google.com" fun loadUrl(url: String): ServiceBuilder{ this.url = url return this }` – Vando Aug 29 '21 at 17:41
  • May I ask you what you mean when you say: "I can not replace the default link"? Do you get the old "google.com" link in your DestinationService? Or do you have another issue? – Vlad L. Aug 30 '21 at 17:29
0

If you use class instead of object, you can try to pass this value in constructor the moment you want to initialise it

Astrit Veliu
  • 1,252
  • 1
  • 12
  • 22