2017-03-27 8 views
6

पर ऑथ हेडर जोड़ना मुझे आश्चर्य है कि क्या डैगर को यह जानने का कोई तरीका है कि नया डेटा उपलब्ध होने पर इसे किसी ऑब्जेक्ट को फिर से बनाना चाहिए।डैगर + रेट्रोफिट। रनटाइम

जिस उदाहरण का मैं बात कर रहा हूं वह अनुरोध हैडर के साथ है जो मेरे पास रेट्रोफिट के लिए है। किसी बिंदु पर (जब उपयोगकर्ता लॉग इन करता है) मुझे एक टोकन मिलता है जिसे मुझे प्रमाणीकृत अनुरोध करने के लिए रेट्रोफिट के शीर्षकों में जोड़ने की आवश्यकता होती है। मुद्दा यह है कि, मुझे रेट्रोफिट के एक ही अनधिकृत संस्करण के साथ छोड़ दिया गया है। यहाँ मेरी इंजेक्शन कोड है:

@Provides 
    @Singleton 
    OkHttpClient provideOkHttpClient(Cache cache) { 
     HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); 
     interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 
     OkHttpClient client = new OkHttpClient.Builder() 
       .addInterceptor(interceptor) 
       .cache(cache).build(); 
     client 
       .newBuilder() 
       .addInterceptor(
        chain -> { 
         Request original = chain.request(); 
         Request.Builder requestBuilder = original.newBuilder() 
           .addHeader("Accept", "Application/JSON"); 
         Request request = requestBuilder.build(); 
         return chain.proceed(request); 
        }).build(); 
     return client; 
    } 

    @Provides 
    @Singleton 
    Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) { 
     Retrofit retrofit = new Retrofit.Builder() 
       .addConverterFactory(GsonConverterFactory.create(gson)) 
       .addCallAdapterFactory(RxErrorHandlingCallAdapterFactory.create()) 
       .baseUrl(mBaseUrl) 
       .client(okHttpClient) 
       .build(); 
     return retrofit; 
} 

@Provides 
    @Singleton 
    public NetworkService providesNetworkService(Retrofit retrofit) { 
     return retrofit.create(NetworkService.class); 
    } 

यह कैसे काम करने के लिए पर कोई भी विचार?

उत्तर

3

the approach द्वारा @oldergod उल्लेख का उपयोग कर के रूप में यह "आधिकारिक" और ज्यादा बेहतर तरीका है पर विचार करें, जबकि दृष्टिकोण नीचे उल्लेख नहीं की सलाह दी रहे हैं, वे समाधान के रूप में माना जा सकता है।


आपके पास कुछ विकल्प हैं।

  1. जैसे ही आप टोकन प्राप्त है, तो आप, घटक है कि आप Retrofit उदाहरण प्रदान की बाहर शून्य एक नया घटक बना सकते हैं और एक नई Retrofit उदाहरण है, जो आवश्यक okhttp उदाहरण के साथ instantiated किया जाएगा के लिए पूछने के लिए।
  2. एक तेज और खराब - SharedPreferences में टोकन सहेजें, okHttp हेडर बनाएं, जो SharedPreferences से टोकन पढ़ने को लागू करेगा। यदि कोई नहीं है - कोई टोकन हेडर नहीं भेजें।
  3. भी भद्दा समाधान - एक static volatile String क्षेत्र ऐलान करते हैं और कदम 2.

क्यों दूसरा विकल्प बुरा है में की तरह एक ही बात करते हैं? क्योंकि प्रत्येक अनुरोध पर आप एसडी कार्ड मतदान करेंगे और वहां से डेटा लाएंगे।

+0

विकल्प के लिए 1. मैं एक नया रेट्रोफिट उदाहरण कैसे मांगूं? – AIntel

+0

आप है मान लिया जाये कि एक 'FooComponent fooCompomnent',' Retrofit' उदाहरण प्रदान करता है। अब आप उस घटक को 'नल' करते हैं और एक नया 'FooComponent' बनाते हैं। – azizbekian

+0

अपने उत्तर को सही के रूप में चिह्नित करते हुए, क्योंकि मैं समझता हूं और देखता हूं कि आपका समाधान कैसे काम करेगा। मेरे सेटअप के साथ समस्या यह है कि मैं निर्माता को अपने प्रस्तुतकर्ता को रेट्रोफिट इंजेक्ट करता हूं जिसे स्वयं ही मेरे विचार में इंजेक्शन दिया जाता है। और मैं इसे अपने विचारों में करता हूं जिनमें से कुछ अपने स्वयं के घटक हैं जो मेरे नेटवर्क घटक पर निर्भर करते हैं। मैं कुछ जादू समाधान की उम्मीद कर रहा था जो किसी भी तरह से मेरे प्रस्तुतकर्ताओं को मेरे सभी विचारों पर फिर से लागू करने के लिए मजबूर करेगा। – AIntel

8

मैंने व्यक्तिगत रूप से okhttp3.Interceptor बनाया है जो मेरे लिए करता है, जो एक बार मेरे पास आवश्यक टोकन होता है। यह तरह दिखता है:

@Singleton 
public class MyServiceInterceptor implements Interceptor { 
    private String sessionToken; 

    @Inject public MyServiceInterceptor() { 
    } 

    public void setSessionToken(String sessionToken) { 
    this.sessionToken = sessionToken; 
    } 

    @Override public Response intercept(Chain chain) throws IOException { 
    Request request = chain.request(); 

    Request.Builder requestBuilder = request.newBuilder(); 

    if (request.header(NO_AUTH_HEADER_KEY) == null) { 
     // needs credentials 
     if (sessionToken == null) { 
     throw new RuntimeException("Session token should be defined for auth apis"); 
     } else { 
     requestBuilder.addHeader("Cookie", sessionToken); 
     } 
    } 

    return chain.proceed(requestBuilder.build()); 
    } 
} 

इसी कटार घटक में, मैं इस इंटरसेप्टर का पर्दाफाश तो मैं sessionToken सेट कर सकते हैं जब मैं की जरूरत है।

कुछ सामान है कि जेक उनकी बात Making Retrofit Work For You यह बारे में बात की है कि।

+0

इसका कोई उदाहरण है। –