Modules and repositories¶
O objecto D2 é o ponto de entrada para interagir com o SDK. O SDK força o objecto D2 a ser um singleton em todo o aplicativo.
Os módulos estão na camada abaixo de D2. Eles actuam como um invólucro para funcionalidades relacionadas. Um módulo inclui alguns repositórios relacionados e pode expor alguns serviços e auxiliares.
Os repositórios atuam como uma fachada para o banco de dados (ou API da web em alguns casos). Eles oferecem recursos de leitura de metadados e leitura/gravação de dados.
Dealing with return types¶
Most of the actions in the SDK are time consuming and must be executed in a secondary thread. To make that explicit, and to notify about the progress of long operations such as metadata or data sync, every asynchronous method is exposed in three flavours:
| Prefix | Return type | Notas |
|---|---|---|
suspend | the value itself | Kotlin suspend function. Recommended, and used in the examples throughout this guide. |
rx | RxJava (Single, Completable, Observable, Flowable) | For apps already built around RxJava. |
blocking | the value itself | Must not be called from the main thread. |
Operations that report progress (metadata and data download, data upload, reserved value download) do not have a suspend variant, because a single return value cannot convey progress. They expose a flow variant instead, which returns a Flow<D2Progress>: flowDownload(), flowUpload(), flowDownloadReservedValues().
// Coroutines
val programs = d2.programModule().programs().suspendGet()
// RxJava
d2.programModule().programs()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.rxGet()
.subscribe { programs -> } // List<Program>
// Blocking, from a background thread
val programs = d2.programModule().programs().blockingGet()
Important
Unprefixed RxJava methods are deprecated in favour of their
rxcounterparts, so that the coroutine variants can coexist with them. The old names still work, but they will be removed in a future release.The table below lists the drop-in replacement, which keeps the RxJava return type. When migrating, consider moving to the
suspendvariant instead.
Deprecated Drop-in replacement get()rxGet()count()rxCount()isEmpty()rxIsEmpty()getUids()rxGetUids()exists()rxExists()add(o)rxAdd(o)set(value)rxSet(value)delete()/deleteIfExist()rxDelete()/rxDeleteIfExist()download()rxDownload()upload()rxUpload()evaluate()rxEvaluate()The same rename applies to most module and service methods (
logIn(),logOut(),isLogged(),checkServerUrl(),validate(), theEventServiceandEnrollmentServicemethods, the reserved value manager, ...): the replacement is the same name prefixed withrx, and asuspendvariant is available as well.D2Manager.instantiateD2()follows the same pattern, replaced byD2Manager.rxInstantiateD2().Independently of that rename,
getPaged(int)is also deprecated, replaced bygetPagingData(int), which returns aFlow<PagingData<M>>instead of aLiveData<PagedList<M>>.
Acessar o banco de dados é demorado e é recomendado fazê-lo em um thread separado usando qualquer um dos métodos. No entanto, os procedimentos que envolvem o acesso à API da web, como login, metadados ou download ou upload de dados devem executado em um thread separado, caso contrário, o Android gerará um erro.
Construção de consulta¶
Repositories offer a builder syntax with compile-time validation to access the resources. A typical query is composed of some modifiers (filter, order, nested fields) and ends with an action (suspendGet/rxGet/blockingGet, suspendCount/rxCount/blockingCount, getPagingData,...).
// Generic syntax
d2.<module>.<repository>
.[ filter | orderBy | nested fields ]
.<action>
// An example for events
d2.eventModule().events()
.byOrganisationUnitUid().eq("DiszpKrYNg8")
.byEventDate().after(Date("2019-05-05"))
.orderByEventDate(DESC)
.withTrackedEntityDataValues()
.suspendGet()
Filtros¶
Repositórios expõem a lista de filtros disponíveis prefixados pela palavra-chave "por". A lista de operadores de filtro disponíveis para cada filtro depende do tipo de valor do filtro: por exemplo, um tipo de valor Data oferecerá operadores comodepois, antes,inPeriods, enquanto um tipo de valor Booleano oferecer isFalse ouisTrue.
Common filter operators include: - Equality: eq(), notEq() - Comparison: gt(), lt(), ge(), le() - String matching: like(), notLike() - Collection: in() - matches any value in the provided list - Null checks: isNull(), isNotNull() - Emptiness: isNullOrBlank(), isNotNullAndIsNotBlank() - available in data value filters, where the event query repository exposes them as isEmpty(Boolean)
Vários filtros podem ser anexados à mesma consulta em qualquer ordem. Os filtros são unidos globalmente usando o operador "AND". Isso significa que uma consulta como
d2.eventModule().events()
.byOrganisationUnitUid().eq("DiszpKrYNg8")
.byEventDate().after(Date("2019-05-05"))
...
retornará os eventos atribuídos ao orgunit "DiszpKrYNg8" AND cujo eventDate é posterior a "2019-05-05".
The in() operator is particularly useful for querying multiple values at once:
// Query tracked entity instances with specific data values
d2.trackedEntityModule().trackedEntityInstanceQuery()
.byDataValue("dataElementUid").`in`("value1", "value2", "value3")
.onlineFirst()
.suspendGet()
Ordenar por¶
Os modificadores de pedido são prefixados pela palavra-chave "orderBy".
Vários modificadores "orderBy" podem ser anexados à mesma consulta. A ordem dos modificadores "orderBy" na consulta determina a prioridade do pedido. Isso significa que uma consulta como
d2.eventModule().events()
.orderByEventDate(DESC)
.orderByLastUpdated(DESC)
...
ordenará pelo descendente EventDate em primeiro lugar e, em seguida, pelo descendente LastUpdated.
Incluir campos aninhados¶
Os repositórios retornam classes que não são uma correspondência exata das tabelas do banco de dados: eles são objectos mais complexos que podem incluir algumas propriedades obtidas de outras tabelas. Por exemplo, a classe Event tem uma propriedade chamadatrackedEntityDataValues que inclui uma lista de TrackedEntityDataValues. O principal motivo para escolher esse tipo de objecto é absorver a complexidade de lidar com tabelas de links para que o aplicativo não precise se preocupar com a construção de links entre objectos.
Devido a problemas de desempenho, esse tipo de propriedade não é incluído por padrão: elas devem ser consultadas explicitamente. Nos repositórios, as propriedades que não são incluídas por padrão e precisam ser consultadas são prefixadas pela palavra-chave "com".
Várias propriedades podem ser anexadas à mesma consulta em qualquer ordem. Por exemplo, uma consulta como
d2.programModule().programs()
.withTrackedEntityType()
...
retornará um objecto aninhado TrackedEntityType.
Ajudantes¶
O SDK inclui alguns auxiliares no pacote org.hisp.dhis.android.core.arch.helpers. Eles podem ser facilmente encontrados no Android Studio pesquisando Helper nos nomes das classes. Eles incluem alguns métodos úteis para realizar operações comuns:
AccessHelper: relacionado ao objeto de acesso (configurações de compartilhamento).CollectionsHelper: operações comuns para coleções.CoordinateHelper,GeometryHelper: manipulação de dados geoespaciais.FileResizerHelper,FileCompressionHelper,FileResourceDirectoryHelper: file resource manipulation.UidsHelper: operações comuns para coleções de objetos com uid.UserHelper: operações relacionadas à autenticação do usuário.ValueType: lista de diferentes tipos de valor e seus validadores.
Lista de Módulos¶
Módulos do sistema:
- importModule
- módulo de manutenção
- systemInfoModule
- settingModule
- dataStoreModule
- wipeModule
Módulos de bloco grande:
- metadataModule
- aggregatedDataModule
Módulos de concreto:
- attributeModule
- categoryModule
- constantModule
- dataElementModule
- dataSetModule
- dataValueModule
- módulo de inscrição
- eventModule
- fileResourceModule
- indicadorModule
- legendSetModule
- noteModule
- organisationUnitModule
- optionModule
- periodModule
- programModule
- relacionamentoModule
- smsModule
- trackedEntityModule
- userModule
- validationModule