यह आलेख
Android घटक ViewModel, LifeCycle और LiveData का उपयोग करने के बारे में बात करता है। ये घटक आपको गतिविधि जीवन चक्र की परवाह नहीं करने की अनुमति देते हैं।
रेट्रोफिट रिपॉजिटरी के साथ संयोजन में आधुनिक
कोराउटीन के उपयोग का एक उदाहरण भी माना जाता है।
fun main(args: Array<String>): Unit = runBlocking { // Wait (suspend) for Result val result: Result<User> = api.getUser("username").awaitResult() // Check result type when (result) { //Successful HTTP result is Result.Ok -> saveToDb(result.value) // Any HTTP error is Result.Error -> log("HTTP error with code ${result.error.code()}", result.error) // Exception while request invocation is Result.Exception -> log("Something broken", e) } }
रिट्रोफिट कोरटाइन्स एक्सटेंशनkotlin-coroutines-पुराना वापसकोटलिन पर रेट्रोफिट के लिए एक्सटेंशन। ये सिर्फ दो फाइलें हैं। मैंने उन्हें प्रोजेक्ट में शामिल किया। आप ग्रैडल में डिपेंडेंसी के जरिए उन्हें कनेक्ट कर सकते हैं। गिथुब पर उपयोग के उदाहरण हैं।
हम एडॉप्टर
addCallAdapterFactory (CoroutineCallAdapterFactory ()) भी कनेक्ट करते हैं।
ServerAPI और रिपोजिटरी एक ही फाइल में हैं
अन्य एपीआईKotlin पर REST API कार्यान्वयन। उसके पास कोई विशिष्ट परिवर्तन नहीं है।
ServerAPI import android.arch.lifecycle.MutableLiveData import android.util.Log import com.jakewharton.retrofit2.adapter.kotlin.coroutines.experimental.CoroutineCallAdapterFactory import kotlinx.coroutines.experimental.android.UI import kotlinx.coroutines.experimental.async import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import retrofit2.Call import retrofit2.http.* import ru.gildor.coroutines.retrofit.Result import ru.gildor.coroutines.retrofit.awaitResult object ServerAPI { var API_BASE_URL: String = getNetworkHost(); var httpClient = OkHttpClient.Builder().addInterceptor( HttpLoggingInterceptor().apply { level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE }) var builder: Retrofit.Builder = Retrofit.Builder() .baseUrl(API_BASE_URL) .addCallAdapterFactory(CoroutineCallAdapterFactory()) .addConverterFactory(GsonConverterFactory.create()) var retrofit = builder .client(httpClient.build()) .build() var netService = retrofit.create<NetService>( NetService::class.java!!) interface NetService { @GET("api/stores") fun getStoreAll(@Header("Authorization") bearer: String): Call<Array<Store>> } }
LiveDataअगला, रिपॉजिटरी पर विचार करें। यह LiveData प्राप्त करने के लिए मुख्य सेवा है। हम लोड स्थिति के साथ LiveData को आरंभीकृत करते हैं:
Resource.loading (नल) । इसके बाद, अनुरोध के अंत की प्रतीक्षा करें प्रतीक्षा की जा
रही है () इस कॉल को Coroutin
async (UI) ब्लॉक में होना चाहिए
अनुरोध के अंत में, हम परिणाम को संभाल सकते हैं। यदि सब कुछ ठीक है, तो परिणाम को
mutableLiveData.value = Resource.success (result.value) में संग्रहीत किया जाएगा
। महत्वपूर्ण बिंदु यह है कि नए उदाहरण के लिए एक लिंक होना चाहिए, अन्यथा पर्यवेक्षक LiveData काम नहीं करेगा। देखें:
नया संसाधन <> (सफलता, डेटा, अशक्त);कोष class Repository { fun getStores(token: String) : MutableLiveData<Resource<Array<Store>>>{ val mutableLiveData = MutableLiveData<Resource<Array<Store>>>() mutableLiveData.value = Resource.loading(null) val req = PostsAPI.netService.getStoreAll(token) try { async(UI) { val result = req.awaitResult() // Check result type when (result) { //Successful HTTP result is Result.Ok -> { mutableLiveData.value = Resource.success(result.value) } // Any HTTP error is Result.Error -> { mutableLiveData.value = Resource.error("Http Error!", null) } // Exception while request invocation is Result.Exception -> Log.d(TAG, result.exception.message) } } } catch (e: Exception) { Log.d(TAG, e.toString()) } return mutableLiveData } }
आवरण डेटाफ्रैगमेंट में त्रुटि को संभालने और राज्य हस्तांतरण के लिए, आवरण -
संसाधन <T> का उपयोग किया जाता है ।
यह तीन राज्यों को संग्रहीत करता है:
public enum Status { SUCCESS, ERROR, LOADING }
डेटा ही:
@Nullable public final T data;
ViewModelStoreViewModel भंडार से डेटा का अनुरोध करता है और इसे
स्टोर चर में
संग्रहीत करता है
val api = Repository() stores = api.getStores(token)
ViewModel class StoresViewModel (context: Context, token: String) : ViewModel() { val stores: MutableLiveData<Resource<Array<Store>>> init { val api = Repository() stores = api.getStores(token) } }
ViewModelProvidersViewModel के मापदंडों को पास करने के लिए, हम मानक
ViewModelProviders का विस्तार करते हैं
उदाहरण के लिए,
LoginViewModel को पास करने के लिए आपको दो मापदंडों (लॉगिन, पासवर्ड) की आवश्यकता होती है। टोकन को
स्टोर व्यूमॉडल में स्थानांतरित करने के लिए, एक (टोकन) का उपयोग किया जाता है
AppViewModelFactory class AppViewModelFactory(private val contect: Context, vararg params: Any) : ViewModelProvider.NewInstanceFactory() { private val mParams: Array<out Any> init { mParams = params } override fun <T : ViewModel> create(modelClass: Class<T>): T { return if (modelClass == LoginViewModel::class.java) { LoginViewModel(contect, mParams[0] as String, mParams[1] as String) as T } else if (modelClass == StoresViewModel::class.java) { StoresViewModel(contect, mParams[0] as String) as T } else { super.create(modelClass) } } }
टुकड़ाStoreViewModel प्राप्त करना:
viewModel = ViewModelProviders.of(this, AppViewModelFactory(requireActivity(), tokenHolder.token)).get(StoresViewModel::class.java)
डेटा परिवर्तन के लिए प्रेक्षक का उपयोग करना:
// Observe data on the ViewModel, exposed as a LiveData viewModel.stores.observe(this, Observer<Resource<Array<Store>>> { storesResource ->
टुकड़ा override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val view = inflater.inflate(R.layout.stores_fragment, container, false) val tokenHolder = TokenHolder(PreferenceManager.getDefaultSharedPreferences(requireActivity())) viewModel = ViewModelProviders.of(this, AppViewModelFactory(requireActivity(), tokenHolder.token)).get(StoresViewModel::class.java) recyclerView = view.findViewById<RecyclerView>(R.id.store_list).apply { setHasFixedSize(true) } return view } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState)
पुनश्च
टोकन को संग्रहीत करने और इसे पूरे आवेदन में उपयोग करने के लिए, मैंने फैबियो कोलिनी से पुस्तकालय / विस्तार का उपयोग किया। आवेदन उनके लेख में अच्छी तरह से वर्णित है। लिंक इस आलेख में Github पर या नीचे एक पृष्ठ पर है।
Fabio Collini द्वारा प्रीफ़ेट्स-प्रतिनिधि class TokenHolder(prefs: SharedPreferences) { var token by prefs.string() private set var count by prefs.int() private set fun saveToken(newToken: String) { token = newToken count++ } }
Gradle implementation 'android.arch.lifecycle:extensions:1.1.1' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.30.0" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.30.0" implementation "com.squareup.retrofit2:retrofit:2.4.0" implementation "com.squareup.retrofit2:converter-gson:2.4.0" implementation "com.jakewharton.retrofit:retrofit2-kotlin-coroutines-experimental-adapter:1.0.0" // If you use Kotlin 1.2 or 1.3 // compile 'ru.gildor.coroutines:kotlin-coroutines-retrofit:0.13.0' // compile 'ru.gildor.coroutines:kotlin-coroutines-retrofit:0.13.0-eap13'
लिंकसभी एक उदाहरण में।Android आर्किटेक्चर घटक नमूनेLiveData अवलोकनकोडिन कॉरटाइन्स का उपयोग कर Async कोडमल्टीथ्रेडिंग और कोटलिन