2017-06-07 19 views
9

में "हैसफैगमेंट इंजेक्टर" का वास्तविक उपयोग क्या है मैंने पहले dagger2 v2.2 लागू किया है, लेकिन अब उन्होंने डैगर.android भाग भी जोड़ा है। तो मैं इसके साथ नमूना परियोजना बना रहा हूँ।डैगर 2

मैं @Provide और @Modules की पुरानी पद्धति के बारे में जागरूक और @Components आदि एनोटेशन हूँ, लेकिन डैगर से 2.8+ वे इस android-समर्थन पुस्तकालय भी शामिल किया है जो @ActivityKey की तरह कुछ नए इंजेक्शन है, @ContributesAndroidInjector, @ Subcomponent.Builder आदि

तो मेरे सवाल का क्या लाभ यह तालिका में लाता है।

क्या यह बेस क्लास के साथ इंजेक्ट विधि जैसी समस्याओं को हल करता है, सभी बाल वर्ग के लिए काम कर सकता है? या कोई अन्य लाभ?

दूसरा प्रश्न - हैसफैगमेंट इंजेक्टर सिर्फ गतिविधि के अंदर खंड लोड करने के लिए है जैसे कि हम खंड प्रबंधक का उपयोग करते थे? या मुझे कुछ याद आ रही है?

पुस्तकालय के दस्तावेज के रूप में सभी लाइब्रेरी उपयोगकर्ताओं के लिए इसके अधिक जानकारीपूर्ण प्रश्न को कम मत करें, ऐसे उत्तर प्रदान नहीं करते हैं।

+1

dagger2 और विशेष रूप से इस नए सामग्री के बारे में मेरी बहुत सीमित ज्ञान से मैं बता सकता है कि आप सुई आधार गतिविधि और आधार टुकड़ा कक्षाओं का उपयोग कर सकते अपने बच्चों के वर्गों के लिए निर्भरता। दूसरे प्रश्न के लिए, यह टुकड़े टुकड़े इंजेक्टर के लिए डैगर के लिए है जिसका उपयोग बनाए गए टुकड़ों में निर्भरता को इंजेक्ट करने के लिए किया जाता है। लेकिन आपको अभी भी FragmentManager का उपयोग करना होगा। –

+0

यहां मैंने अपने डैगर से संबंधित कोड निकाले, मुझे यकीन नहीं है कि यह सही है, लेकिन यह काम कर रहा है। https://gist.github.com/anonymous/45446b3bf2100d1c22520ebf82f0bff3 –

+0

@ क्रिस्टियन पी। जानकारी के लिए धन्यवाद लेकिन फिर भी मैं स्पष्ट उत्तर की प्रतीक्षा कर रहा हूं। जो मुझे स्पष्ट तरीके से अवधारणा को समझने में मदद करता है। – androidnoobdev

उत्तर

2

Official Documentation इस विषय को मेरे विरोध में काफी अच्छी तरह से बताता है।

वैसे भी मुख्य लाभ यह है कि इस

((SomeApplicationBaseType) getContext().getApplicationContext()) 
    .getApplicationComponent() 
    .newActivityComponentBuilder() 
    .activity(this) 
    .build() 
    .inject(this); 

की तरह कुछ करने के बजाय आप बस यह लिख सकते हैं, जो जीवन हर किसी के लिए आसान बना देता है है।

AndroidInjection.inject(this); 
  1. कम बॉयलरप्लेट, आसान रख-रखाव।

  2. पिछला दृष्टिकोण निर्भरता इंजेक्शन की मूल अवधारणा को तोड़ने का एक प्रकार है, एक वर्ग को निर्भरता के इंजेक्शन के तरीके के बारे में कोई जानकारी नहीं जाननी चाहिए।

15

पहला सवाल

डैगर में 2.8+ वे इस android-समर्थन पुस्तकालय भी जो @ActivityKey जैसे कुछ नई व्याख्याएं है, @ContributesAndroidInjector, @Subcomponent.Builder आदि को शामिल किया है तो मेरे सवाल यह क्या लाभ होता है मेज पर लाता है।

यह पहले से ही What are the advantages of using DispatchingAndroidInjector and the other dagger-android classes?

में जवाब दिया गया है यह एक आधार वर्ग है कि सभी बच्चे वर्ग के लिए काम कर सकते हैं के लिए एक सुई विधि नहीं होने जैसी समस्याओं को हल करता है?

डैगर 2 निर्भरता इंजेक्शन के लिए संकलन समय पर कोड जनरेशन का उपयोग करता है। इसमें, यह अन्य निर्भरता इंजेक्शन ढांचे से अलग है जैसे कि गुइस जो रनटाइम पर इंजेक्शन साइटों का निरीक्षण करता है। डैगर 2 को काम करने के लिए, आपको किसी बिंदु पर इंजेक्शन साइट का आविष्कार निर्दिष्ट करना होगा।इसलिए यह की तरह कुछ लिखने के लिए संभव हो सकता है कभी नहीं होगा: एक डैगर 2 घटक अंदर

void inject(Activity activity); 

और यह सब गतिविधियों इंजेक्षन है।

हालांकि, डैगर-एंड्रॉइड में उपलब्ध नई कक्षाओं के साथ कई सुधार हैं। जबकि इससे पहले कि आप के लिए होता है लिखने के लिए:

void inject(MainActivity mainActivity); 

और इतने पर प्रत्येक अलग इंजेक्शन साइट अब आपको निम्न कोड लिख सकते हैं के लिए:

@Module(subcomponents = MainActivitySubcomponent.class) 
public abstract class MainActivityModule { 

    @Binds 
    @IntoMap 
    @ActivityKey(MainActivity.class) 
    abstract AndroidInjector.Factory<? extends Activity> mainActivityInjectorFactory(MainActivitySubcomponent.Builder builder); 
} 

और उसके बाद: अंदर

AndroidInjection.inject(this); 

अपने उचित बिंदु पर मुख्य गतिविधि।

दूसरा सवाल

HasFragmentInjector बस गतिविधि की तरह हम FragmentManager का उपयोग कर करते थे अंदर टुकड़ा लोड करने के लिए है? या मुझे कुछ याद आ रहा है?

HasFragmentInjector बस वर्ग जहां टुकड़ा से अपने AndroidInjector मिलना चाहिए चिह्नित करता है। आप AndroidInjection#inject(Fragment fragment) के लिए कोड on GitHub में खुद के लिए देख सकते हैं:

public static void inject(Fragment fragment) { 
    checkNotNull(fragment, "fragment"); 
    HasFragmentInjector hasFragmentInjector = findHasFragmentInjector(fragment); 
    Log.d(TAG, String.format(
     "An injector for %s was found in %s", 
     fragment.getClass().getCanonicalName(), 
     hasFragmentInjector.getClass().getCanonicalName())); 

    AndroidInjector<Fragment> fragmentInjector = hasFragmentInjector.fragmentInjector(); 
    checkNotNull(fragmentInjector,"%s.fragmentInjector() returned null", 
    hasFragmentInjector.getClass().getCanonicalName()); 
    fragmentInjector.inject(fragment); 
} 

जावाडोक से, इस विधि पहले अभिभावक टुकड़ा है, तो गतिविधि है, तो अंत में आवेदन HasFragmentInjector खोजने के लिए चलता है और सुई AndroidInjector<Fragment> का उपयोग करता है टुकड़े के खेतों।

हालांकि, HasFragmentInjector की उपस्थिति का मतलब यह नहीं है कि आप डैगर 2 का उपयोग प्रबंध टुकड़े शुरू कर देना चाहिए:

public class MainActivity { 

    @Inject CoffeeFragment coffeeFragment; //no! don't do this 
    @Inject TeaFragment teaFragment; //no! 

तुम अब भी टुकड़े जो स्थिर कारखाने तरीकों का उपयोग कर रहा है instantiating की मुहावरेदार तरह से उपयोग करना चाहिए। डैगर 2 टुकड़े के अंदर के खेतों के लिए इंजेक्शन करेगा जब उनके onAttach(Context context) को कहा जाता है कि आप लेनदेन का उपयोग करके टुकड़ा जोड़ते हैं या आप व्यूपेजर को भेजते हैं।

public class MainActivity extends AppCompatActivity implements HasSupportFragmentInjector { 

    @Inject 
    DispatchingAndroidInjector<Fragment> fragmentDispatchingAndroidInjector; 

    ViewPager mViewPager; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     AndroidInjection.inject(this); 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     BeveragesPagerAdapter beveragesPagerAdapter = new BeveragesPagerAdapter(getSupportFragmentManager()); 
     mViewPager = (ViewPager) findViewById(R.id.viewpager); 
     mViewPager.setAdapter(beveragesPagerAdapter); 
    } 

    class BeveragesPagerAdapter extends FragmentStatePagerAdapter { 

     public BeveragesPagerAdapter(FragmentManager fm) { 
      super(fm); 
     } 

     @Override 
     public Fragment getItem(int i) { 
      switch (i) { 
       case 0: 
        return TeaFragment.instantiate(new Bundle()); 
       case 1: 
        return CoffeeFragment.instantiate(new Bundle()); 
       default: 
        throw new IllegalStateException(); 
      } 
     } 

     @Override 
     public int getCount() { 
      return 2; 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      return "tab " + (position + 1); 
     } 
    } 

    @Override 
    public AndroidInjector<Fragment> supportFragmentInjector() { 
     return fragmentDispatchingAndroidInjector; 
    } 
} 

FragmentStatePagerAdapter सही ढंग से टुकड़े के प्रबंधन संभालती है और हम MainActivity अंदर क्षेत्रों के रूप में इंजेक्षन नहीं है: इसके बजाय ऊपर के उदाहरण की, निम्नलिखित कोड एक ViewPager और दो टुकड़े के साथ एक बहुत ही सरल गतिविधि है।

टुकड़े खुद को इस तरह दिखेगा:

में

CoffeeFragment.java:

public class CoffeeFragment extends Fragment { 

    public static CoffeeFragment instantiate(@Nullable Bundle arguments) { 
     CoffeeFragment coffeeFragment = new CoffeeFragment(); 
     coffeeFragment.setArguments(arguments); 
     return coffeeFragment; 
    } 

    @Inject 
    @Named("Coffee") 
    Repository repository; 

    TextView textView; 

    @Override 
    public void onAttach(Context context) { 
     AndroidSupportInjection.inject(this); 
     super.onAttach(context); 
    } 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.fragment_coffee, container, false); 
     textView = (TextView) v.findViewById(R.id.coffee_textview); 
     return v; 
    } 

    @Override 
    public void onResume() { 
     textView.setText(repository.retrieve()); 
    } 
} 

CoffeeFragmentModule.java में:

में
@Module(subcomponents = CoffeeFragmentSubcomponent.class) 
public abstract class CoffeeFragmentModule { 

    @Binds 
    @Named("Coffee") 
    abstract Repository repository(CoffeeRepository coffeeRepository); 

    @Binds 
    @IntoMap 
    @FragmentKey(CoffeeFragment.class) 
    abstract AndroidInjector.Factory<? extends Fragment> bindCoffeeFragmentInjectorFactory(CoffeeFragmentSubcomponent.Builder builder); 
} 

CoffeeFragmentSubcomponent।जावा:

CoffeeRepository.java में
@Subcomponent 
public interface CoffeeFragmentSubcomponent extends AndroidInjector<CoffeeFragment> { 

    @Subcomponent.Builder 
    abstract class Builder extends AndroidInjector.Builder<CoffeeFragment> {} 
} 

:

public class CoffeeRepository implements Repository { 

    @Inject 
    public CoffeeRepository() { 
    } 

    @Override 
    public String retrieve() { 
     return "Coffee!!!!"; 
    } 
} 
+0

उत्तर के लिए धन्यवाद। मैं अभी भी अपनी अगली परियोजना में डैगर का उपयोग शुरू करने से पहले कुछ जवाब ढूंढ रहा हूं। और मैं अगले कुछ दिनों के लिए उपलब्ध नहीं होगा, इसलिए यदि आपको अधिक जानकारी मिलती है तो कृपया मुझे बताएं। और मैं आपको धन्यवाद देता हूं और इसे जारी रखता हूं ... – androidnoobdev

संबंधित मुद्दे