मेरे पास एमवीवीएम आर्किटेक्चर में एक सिक्का और रेट्रोफिट आधारित परियोजना है। मैं 'व्यूमोडेल' के साथ डेटा प्रिंट करना चाहता हूं और इस प्रोजेक्ट को पंजीकृत करने के बाद रन टाइम पर हेडर में 'टोकन' का मान जोड़ना चाहता हूं। लेकिन मैं साझा संदर्भों में सहेजे गए टोकन को प्राप्त करने के लिए आवश्यक संदर्भ संरचना प्रदान नहीं कर सका। मैं इसे अपने सबसे साफ रूप में कैसे संभाल सकता हूं?

 fun createNetworkClient(baseUrl: String) =
        retrofitClient(baseUrl, httpClient())


    private fun httpClient(): OkHttpClient {

        val httpLoggingInterceptor = HttpLoggingInterceptor(HttpLoggingInterceptor.Logger.DEFAULT)
        val clientBuilder = OkHttpClient.Builder()
        if (BuildConfig.DEBUG) {
            httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
            clientBuilder.addInterceptor(httpLoggingInterceptor)
        }
        clientBuilder.addInterceptor { chain ->
            val newRequest = chain.request().newBuilder()
                .addHeader( //I can't get token because there is no context here.
                    "Authorization", "Bearer ${PreferencesHelper.getInstance(context).token.toString()}"
                )
                .build()
            chain.proceed(newRequest)
        }



        clientBuilder.readTimeout(120, TimeUnit.SECONDS)
        clientBuilder.writeTimeout(120, TimeUnit.SECONDS)
        return clientBuilder.build()
    }

    private fun retrofitClient(baseUrl: String, httpClient: OkHttpClient): Retrofit =
        Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(httpClient)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()

ऐप मॉड्यूल

val appModule = module {
    single {
        androidApplication().getSharedPreferences("PREFERENCES", android.content.Context.MODE_PRIVATE)
    }
    single { createNetworkClient(BuildConfig.BASE_URL) }
    single { (get() as Retrofit).create(Api::class.java) } 
    viewModel {
        ContactViewModel(get())
    }
}

MyContactActivity

 private val contactList: ContactViewModel  by viewModel()
    override fun onCreate(savedInstanceState: Bundle?) {
        viewModel = contactList

        super.onCreate(savedInstanceState)
        binding.adapter = ContactAdapter(this)
        binding.layoutManager = LinearLayoutManager(this)

        contactList.getContactList()

        contactList.contactListLiveData.observe(this, Observer { list ->
            if (list != null)
                binding.adapter?.update(list)
        })
    }
2
Hasan Kucuk 28 जून 2019, 17:25

1 उत्तर

सबसे बढ़िया उत्तर

साझा वरीयताएँ प्रदान करने के लिए आप एक कोइन मॉड्यूल बना सकते हैं:

val sharedPreferencesModule = module {

   single {
      androidApplication().getSharedPreferences("PREFERENCES",  android.content.Context.MODE_PRIVATE)
   }
}

और फिर इसे कोइन के साथ उस वर्ग में इंजेक्ट करें जो रेट्रोफिट क्लाइंट उत्पन्न करता है।

संपादित करें

आपको अपने createNetworkClient विधि हस्ताक्षर को संशोधित करने की आवश्यकता है:

fun createNetworkClient(baseUrl: String, preferences: SharedPreferences)

और फिर इसे कोइन के साथ इंजेक्ट करें:

val appModule = module {
    single {
        androidApplication().getSharedPreferences("PREFERENCES", android.content.Context.MODE_PRIVATE)
    }
    single { createNetworkClient(BuildConfig.BASE_URL, get()) }

    ...
}

फिर आपको createNetworkClient विधि में साझा वरीयताएँ प्राप्त होंगी और साझा प्राथमिकताओं से टोकन को पुनः प्राप्त करने के लिए तर्क को लागू करने की आवश्यकता है।

1
Jaime Suarez 28 जून 2019, 17:55