Criação de um Android SDK em estilo de atividade única

Você não surpreenderá ninguém com uma abordagem de atividade única ao criar um aplicativo final para Android. Mas fomos além e usamos No-Activity ao desenvolver o SDK. Agora vamos descobrir por que isso foi necessário, as dificuldades encontradas e como elas foram resolvidas.

SDKs padrão de terceiros no Android

Como os SDKs externos geralmente funcionam no Android? ActivityBiblioteca aberta , realizado algum trabalho, o resultado é retornado se necessárioonActivityResult.

Fluxo de trabalho do SDK padrão.
Fluxo de trabalho do SDK padrão.

, SDK . SDK, :

Pilha desejada de telas de aplicativos e SDK
SDK

, SDK . , , , MapFragment Google. , , .

SDK

  • SDK , - Activity SDK -.

  • , SDK. (: , ).

  • SDK Lock Screen. , Lock Activity.

No-Activity SDK

, , , (Activity) SDK . - SDK . .

SDK sem atividade em fragmentos
No-Activity SDK

, . ?

No-Activity SDK

  • SDK , .. .

  • , SDK - childFragmentManager.

  • , .. .

No-ActivitySDK

  • , Single-Activity.

  • SDK , dagger - ( ).

  • SDK Activity .. requireActivity . SDK.

  • Activity onActivityResult, , , .

  • SDK, .. Activity .

3rd party SDK

SDK. . , dagger2 .

Dagger2 SDK

dagger Application. SDK , Application, , .

, .

internal object ComponentHolder {

    lateinit var appComponent: SdkAppComponent
        private set

    @Synchronized
    fun init(ctx: Context) {
        if (this::appComponent.isInitialized) return

        appComponent = DaggerSdkAppComponent
            .builder()
            .sdkAppModule(SdkAppModule(ctx))
            .build()
    }

}

, init, , SDK , . SDK. EntryPointFragment. SDK. SDK childFragmentManager.

EntryPointFragment ComponentHolder Dagger.

override fun onCreate(savedInstanceState: Bundle?) {
        ComponentHolder.init(requireActivity())
        ComponentHolder.appComponent.inject(this)
        super.onCreate(savedInstanceState)
    }

, ComponentHolder, SDK .

okhttp3 major 4.+. Kotlin, , , code() . SDK, 3, 4 SDK, .

, . 2 flavor:

    flavorDimensions("okhttpVersion")
    productFlavors {
        v3 {
            dimension = "okhttpVersion"
        }
        v4 {
            dimension = "okhttpVersion"
        }
    }
    
    dependencies {
        v3Api okhttp3.core
        v3Api okhttp3.logging

        v4Api okhttp4.core
        v4Api okhttp4.logging
		}

, flavor , code() code.

// Code in v3 folder
class ResponseWrapper(private val response: Response) {

    val code : Int
        get() = response.code()

}
// Code in v4 folder
class ResponseWrapper(private val response: Response) {

    val code : Int
        get() = response.code

}

.

: , :

defaultConfig {
	...
	missingDimensionStrategy 'okhttpVersion', 'v4'
}

Nesse caso, você se livrará do conflito de construção. Caso contrário, simplesmente não haverá uma versão.

Conclusão

O desenvolvimento do SDK, quando comparado a um aplicativo Android simples, é muito mais difícil, mas às vezes mais interessante. Além disso, os requisitos para a qualidade do produto final são maiores - se algo cair, não cairá para você, mas para o seu cliente, o que é muito ruim.




All Articles