2017-07-28 40 views
16

Obecnie eksperymentuję z InstantApps i chciałbym dołączyć do mojego projektu sztylet.Budowanie aplikacji błyskawicznej na Androida z komponentem aplikacji z Dagger'a

Mam do czynienia z problemem konfigurującym aplikację AppComponent. Mój komponent aplikacji zawiera wszystkie moduły sztyletów funkcji mojej aplikacji.

Mam zasadniczo:

  • Jeden moduł aplikacja bazowa zawierający moją klasę aplikacji
  • wiele funkcji z każdym modułem sztyletem za działaniu, wszystkie z podstawką jako zależność.
  • Jeden moduł aplikacji i moduł natychmiastowy importujący wszystkie funkcje i podstawowy moduł aplikacji.

Próbuję znaleźć konfigurację przed dodaniem modułu aplikacji błyskawicznej.

Z dokumentacji i przykładów projektów InstantApps. Wygląda na to, że klasa Application musi znajdować się w Base. Z dokumentacji Dagger, aby ustawić sztylet:

DaggerYourAppComponent.create().inject(this); 

Powinien być zawarty w twojej klasie aplikacji. Jednak wydaje się to niemożliwe, ponieważ AppComponent musi odwoływać się do wszystkich modułów sztyletów funkcji.

moich pytania są:

  • Gdzie należy dodać moduł mój sztylet AppComponent?
  • Czy powinienem zachować swoją aplikację w module aplikacji, a nie w Bazie?
  • Jakieś repozytorium GitHub lub dokumentacja związana z Dagger z aplikacjami błyskawicznymi?

Dziękuję

+0

Od tego [InstantApps Kompatybilny Biblioteki] (https://developer.android.com/topic/instant-apps/prepare.html#identify_tested_compatible_libraries) link, może Dagger nie jest jeszcze obsługiwany ... –

+0

Ten link jest przeznaczony tylko dla bibliotek Google, a nie dla 3. -przyjęcie. – TWL

+0

możesz sprawdzić ten adres https://github.com/ragdroid/instant-app-dagger może ci pomóc. –

Odpowiedz

9
  • Dagger2 jest bardzo wspierane z Instant aplikacji. Można tworzyć klasy komponentów dla każdego modułu funkcji i odpowiadającej mu klasy dostawcy sztyletu, aby odsłonić instancję klasy komponentów dla każdego modułu funkcji.
  • Każda klasa komponentów modułu może zadeklarować metody iniekcji dla klas zawartych tylko w tym module funkcji.
  • Dodatkowo można również zastosować klasę komponentu aplikacji w module podstawowym dla szerokiego wtrysku aplikacji.
  • Klasa komponentu aplikacji może być utworzona w klasie aplikacji zawartej w module podstawowym i wystawiona na działanie innych modułów funkcji za pomocą metody statycznej w klasie aplikacji.

Oto przykładowy kod wstrzyknięcia Dagger2 z aplikacjami błyskawicznymi, aby wszystko było bardziej przejrzyste. https://github.com/willowtreeapps/android-instant-apps-demo

+0

Dziękuję za to @Vishy. Myślę, że masz rację, potrzebuję jednego komponentu na funkcję. Nadal jednak szukam próbki, która korzysta z obsługi androida w sztyletie oraz z "AndroidInjection.inject (MyActivity.this)" i AndroidInjector od [tutaj] (https://google.github.io/dagger/android. html). Każdy plan aktualizacji próbki? –

+0

Aby być bardziej szczegółowym, w kroku 3 [samouczek] (https://google.github.io/dagger/android.html#injecting-activity-objects): '@Component (modules = {... , YourActivityModule.class}) interfejs YourApplicationComponent {} ' Ten krok nie jest możliwy do wykonania, ponieważ mój komponent aplikacji nie jest widoczny w module ActivityModule tak jak w module funkcji. –

0

Napisałem artykuł na ten temat z wieloma szczegółami: Dagger2 for Modular Architecture, ale po krótkiej odpowiedzi.

Musisz użyć Dagger2 w inny sposób. Zamiast używać modułu lub podskładnika dla każdego modułu funkcji, musisz użyć komponentu z zależnością od podstawowego AppComponent.

W jednym module jesteśmy zwykle zrobić coś takiego:

@Singleton 
@Component(modules = arrayOf(NetworkModule::class, RepositoryModule::class, 
        SubcomponentModule::class)) 
interface ApplicationComponent : AndroidInjector<MyApplication> { 
    val userRepository: UserRepository 
    val apiService: ApiService 
} 

@Module 
object NetworkModule { 
    @Provides 
    @Singleton 
    @JvmStatic 
    fun provideApiService(okHttp: OkHttp): ApiService { 
    return ApiSerive(okHttp) 
    } 
} 

Ale mówiłeś, że nie masz dostępu do SubComponentModule który mógłby być w innym modułem lub sztyletu referencyjna modułów w innym module funkcji.

Można po prostu utworzyć nowy moduł sztylet w module funkcji w zależności od ApplicationComponent tak:

@Browser 
@Component(modules = [(BrowserModule::class)], 
     dependencies = [(AppComponent::class)]) 
interface BrowserComponent : AndroidInjector<AppCompatActivity> { 
    @Component.Builder 
    abstract class Builder: AndroidInjector.Builder<AppCompatActivity>(){ 
    /** 
    * explicity declare to Dagger2 
    * that this builder will accept an AppComponent instance 
    **/ 
    abstract fun plus(component: AppComponent): Builder 
    } 
} 

i odpowiadająca im działalność cecha zbuduje komponent:

class BrowserActivity : AppCompatActivity() { 
    override fun onCreate(savedInstanceState: Bundle?) { 
    super.onCreate(savedInstanceState) 
    DaggerBrowserComponent 
     .builder() 
     /** 
     * we have to provide an instance of the AppComponent or 
     * any other dependency for this component 
     **/ 
     .plus((application as MyApplication).component) 
     .build() 
     .inject(this) 
    } 
}