In researching answers for my question here I found (after several days of very frustrating work) references to the kotlin billing library "billing.ktx" which a couple of Developer pages claim
contains Kotlin extensions and coroutines support that enable you to
write idiomatic Kotlin when using Google Play's billing system
but gives neither details nor links for more information. The Play billing examples, "Classy Taxi" and "TrivialDrive" have been rewritten to use Kotlin but hardly "idiomatic Kotlin", and certainly not using coroutines, nor do they use this library. They are now two years old and showing their age in this fast moving arena.
My question is specifically what does this library offer in terms of idiomatic Kotlin or even coroutine support? I am making some headway with some billing client functions (as can be seen in the referenced question) before using this library, but I can't see what difference using it makes. To be even more specific, "launchBillingFlow" looks impossible to convert, but is it?
Just links to somewhere to find information would be enough. Why is it so hard to find more than class definitions for the billing client?
I can find no documentation. Everything in this answer comes from looking through the billing-ktx aar that appears when I add a dependency on this library to my project.
This library looks pretty minimal. It provides three new "result" classes as well as four extension funtions on BillingClient to replace callback-based code with suspend funs.
package com.android.billingclient.api
public suspend fun BillingClient.acknowledgePurchase(params: AcknowledgePurchaseParams): BillingResult { /* compiled code */ }
public suspend fun BillingClient.consumePurchase(params: ConsumeParams): ConsumeResult { /* compiled code */ }
public suspend fun BillingClient.queryPurchaseHistory(skuType: String): PurchaseHistoryResult { /* compiled code */ }
public suspend fun BillingClient.querySkuDetails(params: SkuDetailsParams): SkuDetailsResult { /* compiled code */ }
With these in place, inside a coroutine you can write:
val result = billingClient.querySkuDetails(params.build())
// you can now access result.billingResult or result.skuDetailsList
Rather than something like what appears in the documentation:
billingClient.querySkuDetailsAsync(params.build()) { billingResult, skuDetailsList ->
// Process the result.
}
Related
I'm using #RestrictTo annotation to denote that a function should be used in only in subclasses or tests.
To do that I use the following syntax:
#RestrictTo(value = [SUBCLASSES, TESTS])
public override fun onCleared() {
// Expose protected fun onCleared for tests
}
At first it seemed to be working but my teammates reported Android Studio showing this warning:
I could reproduce this after building the project again.
This error goes away if I remove the TESTS scope from the annotation as if the annotation does not support multiple scopes in values.
Do you think if this is the intended behavior of the annotation?
Can you think another way to restrict a function to the union of two different scopes?
Thanks in advance
The bounty expires in 2 days. Answers to this question are eligible for a +100 reputation bounty.
Ethansocal is looking for an answer from a reputable source:
I have this same problem, and would like to know what the best method is.
I am developing an Android application with Kotlin in which I need to get the current location of the mobile device. I've already found a way to do it in various examples, but I don't know how to integrate this logic according to Clean Architecture with MVVM.
In my architecture I have the following layers: Presentation, UseCase, Data, Domain and Framework. I have the presentation layer organized with the MVVM pattern. Also I use Koin for dependency injection.
I get all the data that my application needs from the DataSources that are in the Framework layer. For example, data obtained remotely or from a database, or data provided by the device (location).
Here is an example of the files involved in obtaining the location from the ViewModel:
ConfigurationViewModel (Presentation layer):
class ConfigurationViewModel(private val useCase: GetLocationUseCase) : ViewModel() {
fun onSearchLocationButtonClicked() = liveData<Resource<Location>>(Dispatchers.IO) {
emit(Resource.loading())
try {
emit(Resource.success(data = useCase.invoke(UseCase.None())))
} catch (exception: Exception) {
emit(Resource.error(message = exception.message))
}
}
GetLocationUseCase (Usecase layer):
class GetLocationUseCase(private val locationRepository: LocationRepository) :
UseCase<Location, UseCase.None>() {
override suspend fun invoke(params: None): Location = locationRepository.getLocation()
}
LocationRepositoryImpl (Data layer):
class LocationRepositoryImpl(private val locationDeviceDataSource: LocationDeviceDataSource) :
LocationRepository {
override suspend fun getLocation(): Location = locationDeviceDataSource.getLocation()
}
LocationDeviceDataSourceImpl (Framework layer):
class LocationDeviceDataSourceImpl(private val context: Context) : LocationDeviceDataSource {
override suspend fun getLocation(): Location =
LocationServices.getFusedLocationProviderClient(context).lastLocation.await()
}
As you can see, in LocationDeviceDataSourceImpl I need the context to get the last location. I don't know what is the best way to provide the context to the DataSource. I have seen several examples but I want to understand what is the best way to do it.
I have seen the following options:
Use AndroidViewModel, to provide the context of the application to the UseCase, to provide it to the Repository to finally provide it to the DataSource. But I am not sure if it is a suitable way, if it is safe and if it maintains the sense of architecture. Based on Alex's answer
The other option that I have seen is to inject the androidContext through Koin to the DataSource, which is another way to provide the context of the application. In this way it would not be necessary for the context to go through the ViewModel, the UseCase or the Repository. Based on maslick's answer
What would be the appropriate way to integrate this logic according to my architecture and why? Or is this problem because of my architecture?
Thanks a lot for your time.
I would simply inject the Context in the Framework layer!
and the reason for that is quite simple, Context class itself is a part of the Android framework, and your framework layer should autonomously be able to access such classes.
Also, note that you don't even need to have a wrapper class around Context when you inject it in your framework layer. Why? because you aren't going to unit test your framework layer classes. Why? because it would use a mix of Android framework classes or some 3rd party libraries(including other Android libs), that are a black box to us and as a software development principle:
We don't mock dependencies we don't own.
I'm trying to learn the Arrow library and improve my functional programming by transitioning some of my Android Kotlin code from more imperative style to functional style. I've been doing a type of MVI programming in the application to make testing simpler.
"Traditional" Method
ViewModel
My view model has a LiveData of the view's state plus a public method to pass user interactions from the view to the viewmodel so the view model can update state in whatever way is appropriate.
class MyViewModel: ViewModel() {
val state = MutableLiveData(MyViewState()) // MyViewState is a data class with relevant data
fun instruct(intent: MyIntent) { // MyIntent is a sealed class of data classes representing user interactions
return when(intent) {
is FirstIntent -> return viewModelScope.launch(Dispatchers.IO) {
val result = myRoomRepository.suspendFunctionManipulatingDatabase(intent.myVal)
updateStateWithResult(result)
}.run { Unit }
is SecondIntent -> return updateStateWithResult(intent.myVal)
}
}
}
Activity
The Activity subscribes to the LiveData and, on changes to state, it runs a render function using the state. The activity also passes user interactions to the view model as intents (not to be confused with Android's Intent class).
class MyActivity: AppCompatActivity() {
private val viewModel = MyViewModel()
override fun onCreateView() {
viewModel.state.observe(this, Observer { render(it) })
myWidget.onClickObserver = {
viewModel.instruct(someIntent)
}
}
private fun render(state: MyViewState) { /* update view with state */ }
}
Arrow.IO Functional Programming
I'm having trouble finding examples that aren't way over my head using Arrow's IO monad to make impure functions with side effects obvious and unit-testable.
View Model
So far I have turned my view model into:
class MyViewModel: ViewModel() {
// ...
fun instruct(intent: MyIntent): IO<Unit> {
return when(intent) {
is FirstIntent -> IO.fx {
val (result) = effect { myRoomRepository.suspendFunctionManipulatingDatabase(intent.myVal) }
updateStateWithResult(result)
}
is SecondIntent -> IO { updateStateWithResult(intent.myVal) }
}
}
}
I do not know how I am supposed to make this IO stuff run in Dispatcher.IO like I've been doing with viewModelScope.launch. I can't find an example for how to do this with Arrow. The ones that make API calls all seem to be something other than Android apps, so there is no guidance about Android UI vs IO threads.
View model unit test
Now, because one benefit I'm seeing to this is that when I write my view model's unit tests, I can have a test. If I mock the repository in order to check whether suspendFunctionManipulatingDatabase is called with the expected parameter.
#Test
fun myTest() {
val result: IO<Unit> = viewModel.instruct(someIntent)
result.unsafeRunSync()
// verify suspendFunctionManipulatingDatabase argument was as expected
}
Activity
I do not know how to incorporate the above into my Activity.
class MyActivity: AppCompatActivity() {
private val viewModel = MyViewModel()
override fun onCreateView() {
viewModel.state.observe(this, Observer { render(it) })
myWidget.onClickObserver = {
viewModel.instruct(someIntent).unsafeRunSync() // Is this how I should do it?
}
}
// ...
}
My understanding is anything in an IO block does not run right away (i.e., it's lazy). You have to call attempt() or unsafeRunSync() to get the contents to be evaluated.
Calling viewModel.instruct from Activity means I need to create some scope and invoke in Dispatchers.IO right? Is this Bad(TM)? I was able to confine coroutines completely to the view model using the "traditional" method.
Where do I incorporate Dispatchers.IO to replicate what I did with viewModelScope.launch(Dispatchers.IO)?
Is this the way you're supposed to structure a unit test when using Arrow's IO?
That's a really good post to read indeed. I'd also recommend digging into this sample app I wrote that is using ArrowFx also.
https://github.com/JorgeCastilloPrz/ArrowAndroidSamples
Note how we build the complete program using fx and returning Kind at all levels in our architecture. That makes the code polymorphic to the type F, so you can run it using different runtime data types for F at will, depending on the environment. In this case we end up running it using IO at the edges. That's the activity in this case, but could also be the application class or a fragment. Think about this as what'd be the entry points to your apps. If we were talking about jvm programs the equivalent would be main(). This is just an example of how to write polymorphic programs, but you could use IO.fx instead and return IO everywhere, if you want to stay simpler.
Note how we use continueOn() in the data source inside the fx block to leave and come back to the main thread. Coroutine context changes are explicit in ArrowFx, so the computation jumps to the passed thread right after the continueOn until you deliberately switch again to a different one. That intentionally makes thread changes explicit.
You could inject those dispatchers to use different ones in tests. Hopefully I can provide examples of this soon in the repo, but you can probably imagine how this would look.
For the syntax on how to write tests note that your program will return Kind (if you go polymorphic) or IO, so you would unsafeRunSync it from tests (vs unsafeRunAsync or unsafeRunAsyncCancellable in production code since Android needs it to be asynchronous). That is because we want our test to be synchronous and also blocking (for the latter we need to inject the proper dispatchers).
Current caveats: The solution proposed in the repo still doesn't care of cancellation, lifecycle or surviving config changes. That's something I'd like to address soon. Using ViewModels with a hybrid style might have a chance. This is Android so I'd not fear hybrid styles if that brings better productivity. Another alternative I've got in mind would maybe be something a bit more functional. ViewModels end up retaining themselves using the retain config state existing APIs under the hood by using the ViewModelStore. That ultimately sounds like a simple cache that is definitely a side effect and could be implemented wrapped into IO. I want to give a thought to this.
I would definitely also recommend reading the complete ArrowFx docs for better understanding: https://arrow-kt.io/docs/fx/ I think it would be helpful.
For more thoughts on approaches using Functional Programming and Arrow to Android you can take a look to my blog https://jorgecastillo.dev/ my plan is to write deep content around this starting 2020, since there's a lot of people interested.
In the other hand, you can find me or any other Arrow team maintainers in the Kotlinlang JetBrains Slack, where we could have more detailed conversations or try to resolve any doubts you can have https://kotlinlang.slack.com/
As a final clarification: Functional Programming is just a paradigm that resolves generic concerns like asynchrony, threading, concurrency, dependency injection, error handling, etc. Those problems can be found on any program, regardless of the platform. Even within an Android app. That is why FP is an option as valid for mobile as any other one, but we are still into explorations to provide the best APIs to fulfill the usual Android needs in a more ergonomic way. We are in the process of exploration in this sense, and 2020 is going to be a very promising year.
Hopefully this helped! Your thoughts seem to be well aligned with how things should work in this approach overall.
In my Kotlin Multiplatform project, I'm trying to access Kotlin types defined in kotlin-stdlib from Swift.
TL;DR: StdLib types/methods seem not to result in header definitions, I'd like a solution that doesn't involve writing lots of boilerplate code
My scenario
I have an interface defined in Kotlin ...
interface MyKotlinInterface {
fun run() : Sequence<String>
}
... and implemented this interface in Swift ...
class MySwiftClass : MyKotlinInterface {
func run() -> KotlinSequence {
// return sequenceOf("foo")
}
}
... there I'm trying to create a Sequence but there are no methods from the kotlin.sequences package available (e.g. generateSequence).
Is it actually possible to access Kotlin framework types or methods beyond what I define in my code -- if yes, how? Furthermore, how can this be achieved without writing boilerplate code?
Further details
Having a look into the generated Objective-C header file, I see definitions for my class (obviously) and basic Kotlin types. What's missing is basically everything from the standard library functionality (I care for everything Sequence-related).
My build.gradle.kts looks like:
plugins {
kotlin("multiplatform") version "1.3.0"
}
kotlin {
targets { /* ... */ }
sourceSets {
getByName("commonMain") {
dependencies {
api("org.jetbrains.kotlin:kotlin-stdlib-common")
}
}
// ...
getByName("iosMain") {
dependencies {
api("org.jetbrains.kotlin:kotlin-stdlib")
}
}
}
}
Having the kotlin-stdlib defined as a dependency for the iOS target, I would expect those to become actually available from Swift.
Minimal working example
https://github.com/panzerfahrer/so-mwe-kotlin-mpp-swift
Current solution approach
The only solution I came up with, is writing the desired function for the iOS target:
fun <T : kotlin.Any> generateSequence(nextFunction: () -> T?): kotlin.sequences.Sequence<T> = kotlin.sequences.generateSequence(nextFunction)
This works ok-ish but is highly unsatisfying as it requires lots of boilerplate code. Additionally, extension functions cannot be made available this way and would require more boilerplate code or even rewriting parts of the standard library.
Desired solution
I like to avoid writing boilerplate code as much as possible. What I actually only care about, is to have (in my case) Sequence fully accessible from Swift. My feeling is, it would be sufficient to make the compiler generate selected or all header definitions for the standard library functionality.
Do you really need lazy computation (aka Sequence) in your Kotlin code?
If no, I would recommend using List<T> instead (and it maps to Swift directly).
For Sequence implementation, a workaround could be to export a factory function from your Kotlin library, e.g. you may declare a function like
fun <T : kotlin.Any> generateSequence(nextFunction: () -> T?)
= kotlin.sequences.generateSequence(nextFunction)
You may select any other factory function for Sequence, that matches your use-case.
In general, there are too many functions in the Kotlin standard library. Exporting them all to Swift will create too many useless symbols in the binary and increase the compilation time.
I deal with loads of architecture design patterns and guidelines to choose from and to follow as an android client-server app developer.
The most popular ones are:
MVP or MVVM
Clean architecture
Repository pattern
Dependency injection technique
and so on...
Due to the strict rules of patterns, a developer has to admit the fact that patterns are just recommendations themselves, and are not required by Android SDK at all.
Same is true for LibGDX. There are no strict rules or requirements provided by LibGDX library, so the developer is free to decide how to write the game.
So the question is:
Are there some recommendations, design guidelines or even standards for LibGDX game developers to follow? How should I write the code (with usage of LibGDX) in a way that other developer can easily understand?
From my experiences, there is no standard everyone is following. libGDX developers come from different backgrounds. Some are backend developers in their day life, some are just hobbyist devs and learn their first development skills.
I see a lot of libGDX open-sourced projects with typical static SomeManager.getInstance() calls, while I prefer to pass-through references (as a backend developer, you will know about the advantages - testability and so on).
Even the libGDX backend itself does not follow one single approach. There are some parts getting references to managers by reflection (which is not good, because you must exclude such classes from obfusciation) and some using static getInstances().
If you also HTML5, you also must respect some GWT-based restrictions, so you are sometimes forced to go a way you would never do when developing Spring Boot applications.
Now that 3 years passed I can answer this question myself.
I found that using ECS (Entity-Component-System) is the best approach for creating games.
With this approach you'll have 3 different purpose objects. As name suggests they are:
Entity - is just a general purpose object which only contains set of component objects, and usually an ID.
Component - is a bag of data. No logic just plain POJO. The data it contains will define the behaviour of Entity which contains the component.
System - is where you put your logic. Every system should process an entity if and only if it contains a very specific set of components.
Engine - is a representation of a scene where all entities live, and are processed by systems.
The easies way of implementing such approach is by using Ashley lib. It's a lightweight implementation of ECS. Although as my experience has shown this works best in a case of real gameplay. If you want to have very specific animations (even of game objects) then use scene2d.
Scene2d represents a more familiar (to vast majority of developers) approach. It's a graph of UI elements which are placed in a hierarchy. There are very useful Actions which can be used to implement your animations. It also works best for any UI that you want to display in your game.
So to sum it all up I have worked out that you should have a couple of classes per screen to have a distinct division of labour.
Screen - I see it as a branch of running code. It contains an Engine (if we need an ECS) and a Stage (if we need an UI). Handles all game events, user input and routing.
Engine - ecs container which knows how to manage its systems, entities and components.
Stage - UI container which knows what UI elements should be present, how they should look and behave.
Simple example in kotlin (NOTE in my real project I use koin DI to bind all together):
class MyGameScreen : Screen, MyGameEngine.Callback, MyGameStage.Callback {
val engine = MyGameEngine(callback = this)
val stage = MyGameStage(callback = this)
override fun create() {
engine.create()
stage.create()
}
override fun render(delta: Float) {
enigne.update(delta)
stage.act(delta)
stage.draw()
}
override fun dispose() {
enigne.dispose()
stage.dispose()
}
override fun buttonPress() {
//handle button press
}
override fun onGameEvent(event: MyGameEngine.Event) {
//handle some game event
}
}
class MyGameEngine(
private val callback: Callback
) : com.badlogic.ashley.core.PooledEngine() {
fun create() {
// create and add all your systems and entities
}
sealed class Event {
// ...
}
interface Callback {
fun onGameEvent(event: Event)
}
}
class MyGameStage(
private val callback: Callback
) : com.badlogic.gdx.scenes.scene2d.Stage() {
val button1 = TextButton(...).apply {
addClickListener { callback.buttonPress() }
}
val label1 = Label(...)
// and so on
fun create() {
val root = Table().apply {
// add all your actors to the root table
}
val rootContainer = Container(root).apply {
setFillParent(true)
fill()
top()
}
addActor(rootContainer)
}
fun startSomeAnimation() {
val action = Actions.sequence(
// your animation
)
addAction(action)
}
interface Callback {
fun buttonPress()
}
}