Android Kotlin LazyThreadSafetyMode.NONE - android

In most of the samples regarding Android View Model and lazy init nobody refers to the parameters which can be used in by Lazy.
From the Kotlin docu:
If you're sure that the initialization will always happen in the same thread as the one where you use the property, you can use LazyThreadSafetyMode.NONE. It doesn't incur any thread-safety guarantees and related overhead.
I can not recall any cases in my project where I access ViewModel properties outside the MainUIThread, so I'm intending to now use LazyThreadSafetyMode.NONE everywhere in my ListFragmentViewModel, but I'm not seeing Google's samples doing this at all, am I missing some cons? The Google IO App 2022 uses LazyThreadSafetyMode.PUBLICATION in some part of the code, but could not find any usages of LazyThreadSafetyMode.NONE.

Related

What happened to CameraX.unbindAll() method?

I'm trying to follow code samples I've found on the web (Gabriel Tanner, Ray Wenderlich, Official Introduction), but I usually get stymied on the very first line:
CameraX.unbindAll()
Compiler complains that unbindAll() is an unresolved reference (Kotlin). The sample code from here is the only reference that does not use it. But all the other sample codes have it, including Google's own videos.
I can't even find any references to this method in Google's docs. What happened? Have changes in the past few months already made all these excited introductions obsolete?
I'm evaluating CameraX to see if it's worth our company's time to switch our code from Camera2 to CameraX. If things are changing this fast, what are the chances that significant code changes will happen in the future?
CameraX has gone through some changes since it was first introduced last year, this is normal since it was still in Alpha, the API surface was changing a bit throughout the alpha versions, but since it's gone into beta, its public API has become more stable.
Going back to your question, binding and unbinding use cases in CameraX is no longer done through the CameraX class, but instead, it is now done using ProcessCameraProvider.bindToLifecycle() to bind one or multiple use cases to a lifecycle, ProcessCameraProvider.unbind() to unbind one or multiple use cases, and ProcessCameraProvider.unbindAll() to unbind all bound use cases.
The tutorials you're using as reference are outdated, even the video from last year's google I/O is outdated, since the code snippets in it are referencing CameraX's first alpha version. However, the link of the codelab you mentioned is -almost- up to date, it's the official CameraX codelab that's maintained by Google. You can also take a look at the official documentation of CameraX, it's more up to date that the tutorials you referenced.

MVVM repository in android

Am working on a huge android project that has more than 50 APIs request
and using the MVVM pattern, My question is:
can I add all the requests in the same app repository or I must create a repository for each service?
As others suggested in the comments you should first define the modules of your app and then create the corresponding Repositories. This way you can easily maintain and test your application.
I strongly suggest you to have a look on this https://github.com/nickbutcher/plaid and mostly this video https://youtu.be/Sy6ZdgqrQp0
A good solution to this problem is, You must not implement all your API calling code to the same repository as it will become a massive single repository class. It will also be violating design principles i.e. rule of 30 as you are saying you have at least 50 APIs to work with.
Also, it is not a good practice to modify a class, again and again, see Open Close Principle.
You can make multiple API calling classes under the same package name.

Using interfaces for ViewModels?

I am currently integrating architecture components into my app according to the official documentation and the sample apps provided by google (sunflower and todo-app). I realized that none of these use interfaces for ViewModels (the sunflower app does not even use interfaces for repositories).
My question is: is it reasonable to just omit the interfaces for ViewModels (including advantages and disadvantages)?
Is it reasonable to just omit the interfaces for ViewModels?
The below is quite general and applicable not just for ViewModels.
Advantages:
less code
Disadvantages:
won't be able to use most of the well-known design patterns;
won't be able to properly unit test classes (no mocking);
won't be able to properly use dependency injection frameworks;
code refactoring when using another concrete implementation.
The answer depends on the complexity of your ViewModel. If you are never going to create more than one implementation of an interface (including mocking), then there is no need to create the interface, so you can reduce the code and the overall maintenance burden.
That said the important things to consider are:
Can you unit test your view model, even without the interface (answer should be yes, otherwise you have some other problems IMO)
Can you still use a dependency injection framework (the answer is yes at least for some DI frameworks like Prism)
Are you only ever going to create one implementation of your ViewModel?
I believe that the mark of a well-designed ViewModel, should have a relatively simple implementation, and be easy to unit-test without having to resort to mocking.

Trying to fit a "clean architecture" on an iOS app

Recently I’ve been rethinking my android architecture project, trying to adapt it to a more “clean architecture”, specifically, the kind of design suggested by “Uncle Bob”.
Which it involves several layers of abstractions, a nice isolation of responsibilities and a very strong dependency inversion achieved by dependency injection; which, ultimately, leads to a very decoupled-portable system. A perfect candidate to be tested by unit testing and integration testing.
In my android implementation I’ve ended up having three different modules or layers:
-domain: entities, interactors, presenters (pure java module)
-data: (acts as a repository to supply the data to the domain) (android library module)
-presentation: ui related stuff, fragments, activities, views, etc (android application module)
So, I’m trying to figure out what would be the best approach on the iOS ecosystem.
I’ve tried creating a project with multiple targets to achieve the same solution:
-domain: command line target (which seems very weird but I think is the most pure swift target available)
-data: cocoa touch framework
-presentation: cocoa touch framework
With this approach I can use these targets in the way I did with android modules. But the first caveat I’ve found it is that I need to add manually every new file to the dependent target.
But my knowledge is very limited in projects with multiple targets. I mean I’ve never created an iOS application with multiple targets. So I don’t know even if the solution would be use a framework (cocoa touch/cocoa) as a target instead of a command line module for the domain layer.
Any thought would be really appreciate.
Thanks!
Uncle Bob's Clean Architecture absolutely applies to iOS, Swift, and Obj-C. Architecture is language agnostic. Uncle Bob himself codes mostly in Java but in his talks he rarely mentions Java. All his slides do not even show any code. It is an architecture meant to be applied to any project.
Why am I so sure? Because I've studied MVC, MVVM, ReactiveCocoa, and Clean Architecture for 2 years. I like Clean Architecture the best, by far. I tested it by converting 7 Apple sample projects to using the Clean Architecture. I've used this approach exclusively for over a year. It works out better every time.
Some of the benefits are:
Find and fix bugs faster and easier.
Extract business logic from view controllers into interactors.
Extract presentation logic from view controllers into presenters.
Change existing behaviors with confidence with fast and maintainable unit tests.
Write shorter methods with single responsibility.
Decouple class dependencies with clear established boundaries.
We also added a router component so we can use multiple storyboards. No more conflicts.
Writing unit tests is greatly simplified too because I only need to test the methods at the boundaries. I don't need to test private methods. On top of that, I didn't even need any mocking framework because writing your own mocks and stubs becomes trivial.
I've written my experience for my last 2 years studying iOS architecture at Clean Swift I also put together some Xcode templates to generate all the Clean Architecture components to save a ton of time.
UPDATE - To answer #Víctor Albertos's question about dependency injection in the comment below.
This is a really great question and demands a long detailed answer.
Always keep the VIP cycle in mind. In this case, the doSomethingOnLoad() method is not a boundary method. Rather, it is an internal method invoked only within CreateOrderViewController. In unit testing, we test a unit's expected behavior. We give inputs, observe outputs, then compare the outputs with our expectations.
Yes, I could have made doSomethingOnLoad() a private method. But I chose not to. One of the goals of Swift is to make it easy for developers to write code. All the boundary methods are already listed in the input and output protocols. There is really no need to litter the class with extraneous private modifiers.
Now, we do need to test this behavior of "The CreateOrderViewController should do something on load with this request data" somehow, right? How do we test this if we can't invoke doSomethingOnLoad() because it is a private method? You call viewDidLoad(). The viewDidLoad() method is a boundary method. Which boundary? The boundary between the user and view controller! The user did something to the device to make it load another screen. So how do we invoke viewDidLoad() then? You do it like this:
let bundle = NSBundle(forClass: self.dynamicType)
let storyboard = UIStoryboard(name: "Main", bundle: bundle)
let createOrderViewController = storyboard.instantiateViewControllerWithIdentifier("CreateOrderViewController") as! CreateOrderViewController
let view = createOrderViewController.view
Simply calling the createOrderViewController.view property will cause viewDidLoad() to be invoked. I learned this trick a long time ago from someone. But Natasha The Robot also recently mentioned it too.
When we decide what to test, it is very important to only test the boundary methods. If we test every method of a class, the tests become extremely fragile. Every change we make to the code will break many, many tests. A lot of people give up because of this.
Or, think about it this way. When you ask how to mock CreateOrderRequest, first ask if doSomethingOnLoad() is a boundary method that you should write test for. If not, what is? The boundary method is actually viewDidLoad() in this case. The input is "when this view loads." The output is "call this method with this request object."
This is another benefit of using Clean Swift. All your boundary methods are listed at the top of the file under explicitly named protocols CreateOrderViewControllerInput and CreateOrderViewControllerOutput. You don't need to look elsewhere!
Think about what happens if you were to test doSomethingOnLoad(). You mock the request object, then assert that it equals to your expected request object. You are mocking something and comparing it. It's like assert(1, 1) instead of var a=1; assert(a, 1). What's the point? Too many tests. Too fragile.
Now, there is a time when you do mock CreateOrderRequest. After you've verified the correct CreateOrderRequest can be generated by the view controller component. When you test CreateOrderInteractor's doSomething() boundary method, you then mock CreateOrderRequest using interface dependency injection.
In short, unit testing is not about testing every unit of a class. It is about testing the class as a unit.
It is a mindset shift.
Hope that helps!
I have 3 series of draft posts in Wordpress on different topics:
In-depth look at each of the Clean Swift components
How to break up complex business logic into workers and service objects.
Writing tests in Clean Swift iOS architecture
Which one of these do you want to hear more first? Should I bump up the series on testing?
In my opinion Clean Architecture is a set of ideas, rules, principles... to make a code better.
[Android Clean Architecture]
With this approach I can use these targets in the way I did with android modules.
You are able create a target[About](application target or framework target...) but it depends on your needs
If you read Architecting Android...Reloaded from Fernando Cejas
you might have seen that I used android modules for representing each layer involved in the architecture.
A recurring question in discussions was: Why? The answer is simple… Wrong technical decision
The idea is that is not necessary to use some build components to implement Clean Architecture

RoboBinding vs Android Binding for MVVM

What are some pros and cons of using RoboBinding vs Android Binding.
eg.
can RoboBinding be used on fragments ?
What about Android binding for fragments ?
Does any use reflection to slow down Android at run time ?
Also which ones can be obfuscated with proguard ?
Can any of the two auto generate a viewModel interface ?
Android Binding info
RoboBinding cast
I've used both and although I like RoboBinding (I even have some contributions to the code) I've switched to Data Binding for all my binding needs.
http://developer.android.com/tools/data-binding/guide.html
It doesn't have some of the bi-directional binding goodness that I like in RoboBinding but it's really solid at this point and from Google directly. It allows you to do some pretty cool stuff
Here's a post I have that goes into Data binding as well as other stuff
http://blog.liffft.com/2016/01/19/rx-java-spock-groovy-android-bindings-android-might-now-be-testable-say-what/
I didn't use Android Binding, but have some experience with robobinding
yes, quite seemlessly
don't know
I didn't notice any problems with forms binding up to 30 properties
to some extent. you have to preserve all PM properties you bind to, constructors and annotations
no
please note that robobinding is not working well with material design and is not working at all with AppCompat 22+
May I also suggest Anvil (https://github.com/zserge/anvil)? The whole library API is only ~10 most important methods. Inspired by React.js.
No reflection used (other than creating views, but XML inflaters use that as well). Can be used with Proguard, but it's only ~100KB when unstripped, so I normally use with without Proguard. Best used with Kotlin, but also supports Java 6/8.
And if you're familiar with React and are looking for Redux implementation - here's one I normally use with Anvil: https://github.com/trikita/jedux
Just want to let people know who may have Googled this as I did today, that RoboBinding is no longer maintained.
Some alternatives could be RoboMVVM or Anvil, but not sure if either of those are maintained either (last commits were in 2014 and 2019 respectively).
At this point I think the safest option is to use Android Data Binding directly, then you don't have dependencies on third-party frameworks that you might have to remove later. And Android Data Binding does now support two-way data binding, contrary to one of the other answers here.

Categories

Resources