oligazar
6/5/2017 - 9:28 AM

MyApp. Dagger2. SubComponent

MyApp. Dagger2. SubComponent

import dagger.Subcomponent
import ru.orgin.glagol.catalog.view.DetailBookFragment
import ru.orgin.glagol.di.module.DetailBookModule
import ru.orgin.glagol.di.module.PlayerModule
import ru.orgin.glagol.player.PlayerFragment
import javax.inject.Scope

/**
 * Created by Admin on 2/6/17.
 * Dagger with sub component
 * use @Scope annotation and
 * apply plugin: 'kotlin-kapt'
 */

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class Payment

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class DetailBook

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class Player

@DetailBook
@Subcomponent(modules = arrayOf(DetailBookModule::class) )
interface DetailBookSubComponent {

    fun inject(detailBookFragment: DetailBookFragment)
}

@Player
@Subcomponent(modules = arrayOf(PlayerModule::class) )
interface PlayerSubComponent {

    fun inject(detailBookFragment: PlayerFragment)
}
import android.app.Application
import android.content.SharedPreferences
import android.preference.PreferenceManager
//import com.facebook.stetho.okhttp3.StethoInterceptor
import com.google.gson.FieldNamingPolicy
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import dagger.Module
import dagger.Provides
import io.realm.Realm
import okhttp3.Cache
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import ru.orgin.glagol.api.GlagolApiInterface
import ru.orgin.glagol.catalog.model.AutoComplete
import ru.orgin.glagol.catalog.model.AutoCompleteModelDeserializer
import ru.orgin.glagol.personal.model.Registration
import ru.orgin.glagol.personal.model.RegistrationModelDeserializer
import ru.orgin.glagol.personal.model.User
import ru.orgin.glagol.personal.model.UserModelDeserializer
import ru.orgin.glagol.repository.RealmController
import javax.inject.Singleton


/**
 * Created by Admin on 12/24/16.
 * Creates instances that are used in network communication
 */
@Module
class NetModule(val baseUrl: String) {

    // Dagger will only look for methods annotated with @Provides
    @Provides
    @Singleton
    fun providesSharedPreferences(application: Application): SharedPreferences {
        // Application reference must come from AppModule.class
        return PreferenceManager.getDefaultSharedPreferences(application)
    }

    @Provides
    @Singleton
    fun provideOkHttpCache(application: Application): Cache {
        val cacheSize = 10 * 1024 * 1024 // 10 MiB
        val cache = Cache(application.cacheDir, cacheSize.toLong())
        return cache
    }

    @Provides
    @Singleton
    fun provideGson(): Gson {
        val gsonBuilder = GsonBuilder()
        gsonBuilder
                .registerTypeAdapter(Registration::class.java, RegistrationModelDeserializer())
                .registerTypeAdapter(User::class.java, UserModelDeserializer())
                .registerTypeAdapter(AutoComplete::class.java, AutoCompleteModelDeserializer())
                .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
        return gsonBuilder.create()
    }

    @Provides
    @Singleton
    fun provideOkHttpClient(cache: Cache): OkHttpClient {
        val interceptor = HttpLoggingInterceptor()
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        return OkHttpClient.Builder()
                .addInterceptor(interceptor)
//                .addNetworkInterceptor(StethoInterceptor())
                .cache(cache)
//                .connectTimeout(30, TimeUnit.SECONDS)
//                .readTimeout(30, TimeUnit.SECONDS)
//                .writeTimeout(30, TimeUnit.SECONDS)
                .build()
    }

    @Provides
    @Singleton
    fun provideRetrofit(gson: Gson, okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .baseUrl(baseUrl)
                .client(okHttpClient)
                .build()
    }

    @Provides
    @Singleton
    fun provideGlagolApiInterface(retrofit: Retrofit): GlagolApiInterface {
        return retrofit.create(GlagolApiInterface::class.java)
    }

    @Provides
    @Singleton
    fun providesRealm(): Realm {
        return Realm.getDefaultInstance()
    }

    @Provides
    @Singleton
    fun providesRealmController(realm: Realm): RealmController {
        return RealmController(realm)
    }
}
import dagger.Component
import ru.orgin.glagol.MainActivity
import ru.orgin.glagol.catalog.service.BookmarkService
import ru.orgin.glagol.catalog.view.CatalogBooksFragment
import ru.orgin.glagol.catalog.view.CatalogCategoriesFragment
import ru.orgin.glagol.catalog.view.SearchResultsFragment
import ru.orgin.glagol.di.module.AppModule
import ru.orgin.glagol.di.module.DetailBookModule
import ru.orgin.glagol.di.module.NetModule
import ru.orgin.glagol.di.module.PlayerModule
import ru.orgin.glagol.main.*
import ru.orgin.glagol.main.HostRecycler.HostRecyclerFragment
import ru.orgin.glagol.mybooks.view.BookmarksBooksFragment
import ru.orgin.glagol.mybooks.view.BoughtBooksFragment
import ru.orgin.glagol.mybooks.view.HistoryBooksFragment
import ru.orgin.glagol.mybooks.view.ListenBooksFragment
import ru.orgin.glagol.payment.PayActivity
import ru.orgin.glagol.personal.view.*
import javax.inject.Singleton



/**
 * Created by Admin on 12/24/16.
 * net module injects GlagolApiInterface and SharedPreferences
 */

@Singleton
@Component(modules = arrayOf(AppModule::class, NetModule::class) )
interface NetComponent {

    /**
     *  factory method to instantiate the subcomponent defined here (passing in the module instance)
     *  - Необходимо прописывать в интерфейсе родителя метод получения Сабкомпонента (упрощенное название Subcomponent)
     *  - Для Сабкомпонента доступны все объекты родителя
     *  - Родитель может быть только один */
    fun plusDetailBookSubComponent(detailBookModule: DetailBookModule): DetailBookSubComponent
    fun plusPlayerSubComponent(playerModule: PlayerModule): PlayerSubComponent

    fun inject(activity: MainActivity)
    fun inject(activity: PayActivity)

    /* Authorization */
    fun inject(fragment: SignInFragment)
    fun inject(fragment: LogInFragment)
    fun inject(fragment: GetPasswordFragment)

    /* Payment */
    fun inject(fragment: SignInPayFragment)
    fun inject(fragment: LogInPayFragment)

    /* Main */
    fun inject(fragment: MainTabFragment)
    fun inject(fragment: NewsFragment)
    fun inject(fragment: SubscriptionFragment)
    fun inject(fragment: HostRecyclerFragment)
    fun inject(fragment: CollectionsFragment)
    fun inject(fragment: CollectionBooksFragment)

    /* Catalog */
    fun inject(fragment: CatalogCategoriesFragment)
    fun inject(fragment: CatalogBooksFragment)
    fun inject(fragment: SearchResultsFragment)

    /* My Books */
    fun inject(fragment: BoughtBooksFragment)
    fun inject(fragment: ListenBooksFragment)
    fun inject(fragment: BookmarksBooksFragment)
    fun inject(fragment: HistoryBooksFragment)
    fun inject(service: BookmarkService)

    // void inject(MyService service);
}
import android.app.Application
import cn.dreamtobe.threaddebugger.ThreadDebugger
import cn.dreamtobe.threaddebugger.ThreadDebuggers
import com.liulishuo.filedownloader.FileDownloader
import com.liulishuo.filedownloader.connection.FileDownloadUrlConnection
import com.liulishuo.filedownloader.services.DownloadMgrInitialParams
import com.liulishuo.filedownloader.util.FileDownloadLog
import com.liulishuo.filedownloader.util.FileDownloadUtils
import io.realm.Realm
import io.realm.RealmConfiguration
import ru.orgin.glagol.di.component.DaggerNetComponent
import ru.orgin.glagol.di.component.DetailBookSubComponent
import ru.orgin.glagol.di.component.NetComponent
import ru.orgin.glagol.di.component.PlayerSubComponent
import ru.orgin.glagol.di.module.AppModule
import ru.orgin.glagol.di.module.DetailBookModule
import ru.orgin.glagol.di.module.NetModule
import ru.orgin.glagol.di.module.PlayerModule
import java.net.Proxy

/**
 * Created by Admin on 12/24/16.
 * Makes initial set up
 */

class MyApp : Application() {

    companion object {
        lateinit var netComponent: NetComponent
        val baseUrl = "http://www.glagolapp.ru/api/"
        val basePaymentUrl = "https://money.yandex.ru/api/"
        val salt = "df90sdfgl9854gjs54os59gjsogsdf"
        val TAG = "FileDownloadApplication"

        fun plusDetailBookSubComponent(): DetailBookSubComponent {
            // always get only one instance
            return netComponent.plusDetailBookSubComponent(DetailBookModule())
        }

        fun plusPlayerSubComponent(): PlayerSubComponent {
            // always get only one instance
            return netComponent.plusPlayerSubComponent(PlayerModule())
        }
    }

    override fun onCreate() {

        super.onCreate()

//        Debug.startMethodTracing("application")

        initRealm()
        initDagger()
        initFileDownloader()
        // See Stetho gist for more details
        StethoUtils.install(this)
    }

    private fun initRealm() {

        Realm.init(this)

        val configuration = RealmConfiguration.Builder().build()
//        val configuration = RealmConfiguration.Builder()
//                .name(Realm.DEFAULT_REALM_NAME)
//                .schemaVersion(0)
//                .deleteRealmIfMigrationNeeded()
//                .build()
        Realm.setDefaultConfiguration(configuration)
    }

    private fun initDagger() {

        // Dagger%COMPONENT_NAME%
        netComponent = DaggerNetComponent.builder()
                // list of modules that are part of this component need to be created here too
                .appModule(AppModule(this)) // This also corresponds to the name of your module: %component_name%Module
                .netModule(NetModule(baseUrl))
                .build()

        // If a Dagger 2 component does not have any constructor arguments for any of its modules,
        // then we can use .create() as a shortcut instead:
        //  netComponent = com.codepath.dagger.components.DaggerNetComponent.create();
    }

    private fun initFileDownloader() {
        // just for open the log in this demo project.
        FileDownloadLog.NEED_LOG = true

        /**
         * just for cache Application's Context, and ':filedownloader' progress will NOT be launched
         * by below code, so please do not worry about performance.
         * @see FileDownloader#init(Context)
         */
        FileDownloader.init(applicationContext,
                DownloadMgrInitialParams.InitCustomMaker()
                        .connectionCreator(FileDownloadUrlConnection.Creator(FileDownloadUrlConnection.Configuration()
                                .connectTimeout(15000) // set connection timeout.
                                .readTimeout(15000) // set read timeout.
                                .proxy(Proxy.NO_PROXY) // set proxy
                        )))
        // Init the FileDownloader with the OkHttp3Connection.Creator.
//        FileDownloader.init(context,
//                DownloadMgrInitialParams.InitCustomMaker()
//                        .connectionCreator(OkHttp3Connection.Creator()))

        // below codes just for monitoring thread pools in the FileDownloader:
        ThreadDebugger.install(
                ThreadDebuggers.create()
                        /** The ThreadDebugger with known thread Categories  */
                        // add Thread Category
                        .add("OkHttp").add("okio").add("Binder")
                        .add(FileDownloadUtils.getThreadPoolName("Network"), "Network")
                        .add(FileDownloadUtils.getThreadPoolName("Flow"), "FlowSingle")
                        .add(FileDownloadUtils.getThreadPoolName("EventPool"), "Event")
                        .add(FileDownloadUtils.getThreadPoolName("LauncherTask"), "LauncherTask")
                        .add(FileDownloadUtils.getThreadPoolName("BlockCompleted"), "BlockCompleted"),

                2000
                /** The frequent of Updating Thread Activity information  */

        ) { debugger ->
            /**
             * The threads changed callback
             */
            // callback this method when the threads in this application has changed.
        }
    }
}