Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I have two questions:
How to handle events, like user logged in etc.
Let's say I have repository and I am calling a Repo.function in my viewModel, and that ViewModel.method is called in my activity, when user presses the button. So, in some time my Repo.method completes and returns 200, and says my user is logged in. The question is, how my android view ( activity / fragment ) should now that it has to navigate? Currently I use EventBus to post and subscribe to such events.
How to handle network loading states: default/loading/completed
Currently I have a separate singleton that has ObservableFields for loaders like val isTokenLoading = ObservableField(false)
In my viewModel I hold ref to that singleton.isTokenLoading
My view binds to that viewModel's field
And in this way I handle UI changes during loading progress
What is the best way to do such things?
For your first question, I would say that the Observer pattern is the way to go (and the one people usually choose). For instance, RxJava fits perfectly in your use case, and you can even use it with LiveData nowadays. You would launch the request on your ViewModel, create an Observable from the response, perform all the operations you need, and do one of the following: subscribe to the final Observable on your view, or subscribe to a LiveData on your view, while updating it through the observable subscription on your ViewModel (I prefer the latter since it keeps the RxJava dependencies out of the view). You have tons of examples online with implementation details on this.
As for your second question, you're already using the Observer pattern (which, again, is the way most people do it), but keeping all loading fields in the same class seems to me like a code smell. It would probably be better to store them on the class that has to deal with them.
Edit: I just came across an article on AndroidPub exploring exactly what you want: https://android.jlelse.eu/android-architecture-communication-between-viewmodel-and-view-ce14805d72bf
you should use observer pattern. your repository can return a flow (in kotlin coroutine package) and you can observe this flow in you viewmodel. then you can expose this flow to a live data and observe this live data in your fragment or activity. using live data will help you to avoid memory leak.
for handling network states you can have another live data and post state of network to that. and of course observe it in view if you want.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
My app is mostly used outdoors, so there is a Firestore load problem if there is no internet. When a user comes back home, he will have wifi but the app is closed and will not sync. Again when the user goes out and opens the app, there might not be an internet connection and the loop goes on.
What is the best way to sync Firestore in the background? There is BroadcastReceiver option but it is stated that WorkManager should be used instead. Also, there is LiveData but I can't find a Java example, so... what is best? (an example would be nice)
EDIT I had to delete some of the things because my question "is not focused enough"!?!?!?!
so there is a Firestore load problem if there is no internet.
There should not be any problems when the user has no internet connection, and this is because Firestore has its own default caching mechanism:
For Android and iOS, offline persistence is enabled by default.
You say:
When the user comes back home, he will have wifi but the app is closed and will not sync.
It won't sync unless you are listening for real-time changes. Besides that, it's always recommended to remove the lister according to the life-cycle of your activity. So if you are using addSnapshotListener() you attach a listener that gets called for every change that takes place in your database. So this is happening also when your app is closed. Not removing the listener might produce unwanted bills. So it's mandatory to detach the listeners before the activity gets destroyed. For more info, please check the following links:
How to set addSnapshotListener and remove in populateViewHolder in RecyclerView Item?
How to stop getting data in Firestore?
#1. It's not recommended to do that. However, JobDispatcher is old and deprecated, and no longer available, not the BroadcastReceiver class. But if need, you should use WorkManager instead. If you must absolutely use JobDispatcher, which I recommend against it, the source code is archived here. So please read about how to migrate from JobDispatcher to WorkManager.
#2.
Can I use test DB for production and change permissions to read-only? Does that test DB have an expiration date?
Each database has its own Security Rules. So you should choose to secure your data according to your needs. However, there is no expiration date involved, but you can use something like this:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.time < timestamp.date(2021, 08, 05);
}
}
}
To limit the access to the database until tomorrow, August 5th, 2021.
#3. You can use the database also without security rules. But most likely you should consider using them. Most likely you shouldn't use the username, nor the email address, but UID that comes from the authentication process.
#4. Yes, every CRUD operation counts against your free quota. And yes, there's a minimum of one document read, even if the query yields no results. So if your query doesn't return any results, you have to pay one document read.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm new to Android, but I've done quite a bit of server side Java.
I was reading about Intents, and in particular about the difference between sending extra data (classes) via Serializable vs Parcelable. There seems to be a consensus that Serializeable has bad performance, and Parcelable is to be preferred. In some places I've seen it stated that Serializeable is bad because it uses reflection.
That leads to a couple of questions for me:
Is reflection in general considered bad? Should I avoid any library that relies heavily on reflection? For example, if I need JSON deserialization (from some web service) should I not be using Jackson or Gson? Is that org.json garbage really "best practice" in Android-land?
If I really should avoid reflection (and thus Serializable), is there any alternative to the ugly, boilerplate-heavy Parcelable? The Intents are all explicit, and I'm not broadcasting them outside the app. I guess I don't understand why in-process messaging can't just pass a reference to the object inside the Intent.
RE question #2:
I guess I don't understand why in-process messaging can't just pass a reference to the object inside the Intent.
Parcelizing (or serializing) the object allows Android to re-create it when the containing activity is re-created itself. Android controls the lifecycle of activities - and can at anytime destroy your activity, even if it is active/visible (e.g screen rotation, to reclaim memory to handle an incoming phone call, ...). When Android re-creates your activity, it passes you an object called a Bundle that includes all your parcelized objects. This allows you to restore the state of your activity, but note that these are not the original objects - they have been re-constitued from their parceled representations.
is there any alternative...?
If you want to be able to properly re-create your activity, then parcelization and serialization are your choices. I would not be so fast to rule out serialization however. While in general it is less performant, in many cases, this will probably not be user-detectable. Keep in mind that Android was designed at a time when mobile devices has significantly less processing power than they do today. Thus performance optimizations like parcelability were likely more of a concern.
One alternative worth mentioning, which is probably even less performant would be to write the object to disk yourself. Then in the intent, pass a pointer to the file (or the database record). A variation on this would be to use Android SharePreferences to save the data. I only mention this because passing large amounts of data in an Intent can sometimes fail. There is no hard limit on the max object size, but many people, including me, have seen this failure.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
From week I have been searching of a true explanation and implementation of MVC using java, but something i have noticed is that every one implement it differently, so I would be grateful if you give me a useful link or e-book about it, and I need these questions to be answered :
How to inform the modal of the changes happen on the view, since the modal is observable adnd not observer ?
How to inform the view of the changes happen on collections (adding an item to an arraylist), because to add an item this will be happen on the controller handler and the controller is not observable.
Is it a must to work with MVC in the big projects.
The basic idea is:
The trigger for change can be either the controller
(=response code for user inputs, such as keyboard/mouse clicks), or application
decision. E.g. if you have a text field showing a price, the trigger to change it could
be explicit user typing, or a message from the bank.
each such trigger updates the model (and the model only).
In my price example, it would change the model (that backs the text field).
On change - the model fires events, which cause the view to re-render
Thus, to your first question: there's no need to "inform the model that changes happen on the view". The view shouldn't change on its own. The closes thing is keyboard/mouse clicks, that would invoke the CONTROLLER.
To your second question: "how to inform the view of the changes happen on collection" - the collection should be in the model. The controller would then do "model.addItem" which would fire an event for the view
Regarding the use in big projects... you'd probably get different opinions on it.
"Atomic" components would most likely follow this pattern strictly (button, textfield, or similar custom components). The debate would be about larger scales with complex/compound data. E.g. if my main logic resides on a database, how to I inform various screens that something changed. Both the screen and the database hold complex compound data (e.g. user plus his product recommendations plus shopping cart), and you need to decide on the granularity of events : on some simple applications I settled for the application layer sending 'Entity-level events' (such as 'user changed', 'product changed') to which the UI layer registered directly, so it wasn't 100% classical MVC. On other cases I took the trouble to build a compound Model that exactly reflects the screen data.
For the first part, I advise you to start at Wikipedia page on Model–view–controller. You will find a decent explain and other links.
For your first questions, you simply have to think about the workflow. The interaction with user occurs is the view. Then on an action of the user the controller takes the input, optionnaly reformats and passes it to the model in a format known to the model. In theory, the model then updates the view (in web applications, the controller collects data from the model and passes it to the view, so the update model -> view is indirect).
For the second, if you are in a situation where the model can directly update the view (Desktop application or specialized components such as java applets) no problem. If the model cannot directly update the view (typical in web applications), the update will be visible on next interaction. And in fact it happens exactly this way, when you see a web page with gauges displaying values constantly up to date : the browser is instructed via javascript or html meta tags to refresh its state at short time intervals. But when you say to add an item this will be happen on the controller handler, it is only true is this is caused by an interaction from the user (and the view knows it has to update its state, or is instructed to do so via the controller). But the model can be modified by many other ways, interaction from other users, real time probes, back office operations, etc.
The third question is a bit a matter of opinions. What is true is that separation of concerns is recognized as a good design because the different layers can be developped and tested independently (ot a certain extend). That separation allows to change technology in one layer without changing the others (even if this is often theorical). But IMHO the greatest benefit is that you have plenty of frameworks implementing MVC pattern. Choose one, and the greatest part of boiler plate code will be offered by the framework without you having to write and test it. All that giving a reduction of developpement time and of possibilities of mistakes.
My conclusion will be that (like others said in theirs comments) what is important is understanding the theory and the theorical benefits of MVC patterns and separation of concerns. Then depending of what you have to develop and you environment (technologies knowned or allowed) choose a framework that will exempt you to write boiler plate code, and spend the saved time to carefully analyze what all that is for, and what users expect.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I am confused how MVC will work with GUI swing application. I have worked with PHP MVC but that is totally different. I understand what MVC stands for. But what making me confused is different variation of doing it in GUI swing programming. It is hard to conclude particular thing from different articles in web. Who should know whom? I mean what will be the relation between model view and controller? Should controller know both model and the view? I would like to an simple example if possible to illustrate this (like and simple button which will update a label)
If i am not asking more i would like to get sugetions of MVC book which is writtern Swing in mind.
If you ask 10 different people "What does MVC mean?" you'll probably get 10 different answers. I'm personally partial to this definition of MVC (at least for non-web apps):
Model-View-Controller Design Pattern
Basically, the only functions the controller serves is to instantiate model and the view as the application starts up and connect them to one another. Everything else is just proper decoupling of your program's data and logic (model) from how you choose to display it to the user and allow user interaction (view).
There are many different interpretations of MVC for Java. I will try to provide a basic explanation, but as I said, others may disagree on this.
A theoretically 'pure' interpretation of MVC involves the following:
Model does not know about view
View does not know about model
Controller connects model and view in such a way that it provides data from the model to the view, handles 'events' in the view or the model, and updates the model accordingly based on what is happening in the view. It can also just handle an event in the view and provide a result back to the view, for example, a calculator.
Here is a possible/simple example:
The goal of this hypothetical application is to take a String in the model, get it to the GUI (view), allow the user to change the string, and update the aforementioned String value in the model. This example is more or less as decoupled as possible.
Model:
Contains a String variable
View:
Displays String variable.
Takes user input that allows change to the String.
Controller (the 'glue'):
Listens to Model via a customized listener for the String.
Provides this String to the view for the user to see
Listens to the view via a customized listener for the user to change the String.
Takes this new String and provides it to the Model, updating the original String.
One of the key things behind MVC is the Observer Pattern Theory.
Although one takes certain risks using wikipedia, it generally does a good job conveying the basics behind MVC. http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
Here is the link for a discussion on the 'pure' implementation and the source of the interpretation.
http://www.youtube.com/watch?v=ACOHAR7PIp4
Here is a link with a very good explanation of a similar MVC interpretation and the theory behind it:
http://www.youtube.com/watch?v=CVxt79kK3Mk
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm making a customer administration software. There are several JPanels with much content on it, constantly communicating with a database. In the database is customer data, products etc.
For a faster access to the database data, at first I load it all in its own ArrayList, e.g. ArrayList<Customer>. If the user changes this data, it has to be changed in both the class and the database.
As the JPanel View looks very "full" (crammed with other JPanels and JTabbedPanes, switching through with the CardLayout), I thought it would be better to create an own class for every "main" JPanel and link them all with View.
For example an own class for the JPanel Customer, where all the customer data can be seen and edited, the same for products etc.
Does is make sense or is it inconvinient? I only want to do so to outsource the code and to make the classes clearer, especially View.
Is there something like a design pattern dealing with this problem?
So your program consists of a single class that subclasses JPanel and that contains references to all other components used in your UI? And you want to know if you should break out portions of that UI into other classes.
In short YES. You can always decompose any class into aggregated classes by moving portions of that code out into a new class, and have the original class contain a reference to the new class. This is called delegation or Extract Class refactor. You can read about this technique in Martin Fowler's Refactoring book.
Creating other UIs that are parts of the total UI, like CustomerPanel, is a good way to think about it. By doing this you can also decouple parts of your UI. Be careful when you create these smaller classes to move all dependencies to the new class. If you feel like passing a reference back to the main UI to the aggregated class then you probably haven't fully decoupled your classes. That should be a sign either you haven't given enough responsibility to the class you are extracting, or there is some other dependency they should be sharing.
Basically the rule is if you extract a class, it shouldn't have a reference back to the class that contains it. References should be more of a tree than a graph. It's ok for them to share a model class, but its not ok to create cycles between views.
You probably would find this interesting:
GUI guidelines for swing
I am not sure if I understood your intent, but looks like you want to achieve the level of decomposition which will allow you to outsource certain UI components and reuse them, well, basically achieve as lower coupling as possible. Apart from what #chubbard said, I would suggest you to look into MVP pattern and use event-based interaction between components rather than referencing them. This can eliminate unwanted dependencies and bring more reusability.