When I design models layer, there are two way to design my interface. Synchronized or asynchronized.
A. asynchronized design:
interface Callback<T> {
void success(T t);
void failure(Throwable err);
}
interface UserAPI {
void getProfile(Callback<User> callback);
}
B. Synchronized Design
interface UserAPI {
User getProfile();
}
They both have some benefit. A is non-blocking, the UI layer can use it directly. B is blocking, but it is easy to test, the design is much simple, but the UI layer should make a thread to handle it.
I really care about agility development, easy to maintain, keep the whole project neat. Which design should I use?
Ultimately, this is more a question of what you want your API to accomplish, how easy is it to use, performance impact, etc. Asynchronous designs, when done correctly, can help with some performance and API usage restrictions. But, they also tend to be harder to implement correctly and even understand by end users. Synchronous APIs tend to be easier to understand, but come with more restrictions (as you noted with use on the UI thread.) As far as backing implementation, async can also be harder to understand and maintain. I don't think agile development models really influence this, as well as the project maintenance. I would try to ensure those working on it (employees, open source contributors, etc.) are good developers who understand both approaches, write easy to understand and well structured code, and understand the goal of the API.
My recommendation: implement an API which has both async and sync versions available. Maximum flexibility, best of both worlds. Just be sure to document both sets of APIs so users know the semantics of using both.
I think it depends on a particular task. You can't choose either way for the whole project, as it usually consists of multiple parts. As a general rule, each task should be reduced to the synchronous behavior whenever it's possible, for the sake of simplicity.
If an operation is done over a fixed period of time and isn't much
longer than other operations, you can call it synchronously in the
UI thread.
If the execution of an operation may take long or unlimited period
of time, or it depends on some external conditions (e.g. network
connection, system load) and doesn't interact with the UI layer, then I'd use the synchronous design in a background thread.
If the same operation as in the previous paragraph causes updates to the GUI, then obviously the async design should be implemented.
Internal use
I would say it depends on how you will be using this API interface. If it's going to be used internally then it's a matter of where would you like to handle background threads. It's completely up to you.
Published API
In case your API is going to be published then actually it depends on developers needs. Some like to handle threading by them self deciding if it's going to be a single thread queue, multithreaded simultaneously solution or combination of both. For them SYNC API is perfect.
On the other hand some developers may not care about threading and just want get the result as easier as possible. For them ASYNC is perfect.
Recommendation
So it's seem that most probably you will have to implement both. It's most appreciated by developers and reach wide audience. For example have a look at one of the most popular network API Retrofit. They probably had the same decision to make and they implemented SYNC and ASYNC.
RETROFIT SYNC EXAMPLE
#GET("/user/{id}/photo")
Photo getUserPhoto(#Path("id") int id);
RETROFIT ASYNC EXAMPLE
#GET("/user/{id}/photo")
void getUserPhoto(#Path("id") int id, Callback<Photo> cb);
Related
I have an Android app made using Flutter.
Currently, most of the business logic runs on Android native Kotlin, but I love Dart so I am considering moving a lot of the logic to Flutter.
Is there any concern about converting Kotlin's coroutines to Dart's isolate?
There are no general concerns that I'm aware of. Although there are some points that you need to consider before doing the change.
The concurrency paradigm changes from multithread to single thread. This means that you should not think of changing coroutines to isolates, since you will not be using isolates so often or for the same purposes as coroutines.
Isolates are used for "extreme/unique" cases, if you want to perform a long running operation, you normally shouldn't opt out for an isolate, you should perform that with the simple async/await.
It's simpler to use async/await since you don't have to worry about resource allocations or race conditions, but at the same time it allows you to do "dirtier" things, to the responsability is on you.
Last thought on Isolates: they are a separate process so communication between isolates is only done through messages, so basic data should be passed between them and that could give you some headaches if you want to return some big data. (Of course everything is possible with serialization)
Hope this helps you to choose, if not, feel free to comment and we can discuss this further.
this is more an architectural question or also maybe a question of point of view.
Many Android libs have an reactive approach in there APIs. e.g. Volley
, Volley have a nice JsonObjectRequest to put it into a RequestQueue and in the callback onResponse you can handle the response.
Or in Picasso you have also an async call to just load the picture in a given ImageView.
In the new Persistent Tool ObjectBox for Android you have also an reactive approach to set and query data from the database.
So my question is, where are the great needing of RXJava in Android? In which UseCases is RXJava essential?
Reactive is not the same as "observer pattern". Call backs are not the same as reactive. Custom-fitted call back interfaces are much more specific and not as easy to generalize as the reactive implementation of RxJava.
RxJava follows the observable contract, meaning that its behavior is consistent within itself, and that behavior is readily generalizable.
RxJava uses a basic set of operators, with Java generics, to provide a very rich customization portfolio. An Observable<CustomJsonObject> is known to behave in the same way as an Observable<Long>.
Given (1) and (2), you will find that you can compose reactive operators to get customized behavior. Hence, customJsonObjectObservable.distinctUntilChanged() will behave in the same way that longObservable.distinctUntilChanged(). You don't need to create a custom class that stores the previous item for comparison, as the operator takes care of that for you.
Introducing the passage of time or multiple threads is done using operators, and these aspects are also composable. The interval() operator provides periodic updates, the buffer() operator collects data that arrives within a period, and the timeout() operator monitors data and announces when it is not present in a time period.
Point (4) is probably the biggest win for RxJava. Reasoning about the passage of time, especially in the presence of multiple threads of control, is very hard. RxJava brings those difficult areas under control. Hard problems are not quite so hard to solve, and very hard problems can often be decomposed into areas with easier solutions.
Volley does not address the hard issues. It provides asynchronous responses, and addresses only a fraction of item (1) above. It does not address (2), (3) or (4).
Recently, I try to use MVP Pattern in my android project.
I know that I can't do bussiness logic job in View layer. View must deliver all works to Presenter layer then wait for the result from Presenter.
View should do anything in UI thread. But Presenter may do something in Sub-Thread.
How do I control MultiThreading in View layout and Preseneter layer?
Any help will be highly appreciated.
You have two directions you need to communicate:
a) non-UI to UI thread
and
b) UI thread to non-UI thread.
For the first case, a popular way these days is to use runOnUiThread()
Here's a nice survey of this technique and other popular options:
http://www.intertech.com/Blog/android-non-ui-to-ui-thread-communications-part-1-of-5/
As for the other direction, it is not typically necessary unless you have slow blocking operations. It is more a question of clean organization of your source code. A modern technique for sending results back from View to Presenter is using custom interfaces in Fragments like this in the "Communicating with the Activity" section:
http://developer.android.com/guide/components/fragments.html
Note that you should not put long running operations on the UI thread because it will make your app feel sluggish. Try to run them on a different thread if they will take more than 50 milliseconds or so.
Android already separates the functionality of the UI and the controller (or Presenter). It's really your job to separate it even more to make it follow the MVP pattern stronger. The view is on its own thread separate from your presenters. You won't need to do anymore threading for that unless you'd like to for whatever reason.
When I say separating it farther I just mean implementing a structure that abstracts the handling of data to be able to be reused or changed easily.
If I want to make a request from an Android device to a remote service, I can use AsyncTask, AsyncTaskLoader, Intent, etc to make the a request apart from the UI thread. It seems there are a lot of options, but I am confused how to choose among them. Could you explain when and which to use? Also, are there any other options besides the ones I have mentioned?
This is an extensively discussed question, since Android provides a long list of mechanisms capable to handle service calls asynchronously, besides the one you mentioned there's also:
IntentService
Native Threads
Now, the key point in your question is "When to use it" and here would be my answer:
In software the only golden rigid rule is the "It depends rule", there's no hard rules for anything in software development there's always different ways to approach a problem in software (i guess that's the reason of the word "soft" in it...) and that's exactly why it always depends, it depends on whatever you need and although one approach might be the most common way to do it like for example "AsyncTask" it doesn't mean at all that AsyncTaks is always the way to go, it always depends on the factors and needs that affect your functionality. There's plenty of things that nowdays get executed using AsyncTaks when maybe all you need could be just a regular common Native Thread.
The only way to be able to make a decision towards the most appropiate approach would be knowing ALL the features around a tool, like for example most people 90% of the time use AsyncTaks just to run doInbackGround on separate thread, but might not even need preExecute, publishProgress, postExecute, etc, and that's something a Regular Thread could do, just like this example there's features for every single object provided in order to do remote calls, however as i already mentioned several times, it all depends on what you need and what tool fits better your needs. Remember there's no hard coded rules for "How, When, and What" to use in software, IT ALL DEPENDS, and making good decisions in that "DEPENDS" makes the difference between good developers from excellent developers...
This is a list of things i usually take on count to implement either one way or another, this list do not apply for all the scenarios but might give you an idea.
AsyncTaks- I know is a good idea to make use of asynctaks when the functionality needs to be monitored, by monitored i mean, i need to keep track of progress during my job, like (download/task progress), because that's exactly what the AsyncTask was originally created for, it was created attached to "The Task Pattern", and if i don't need to make use of at least two methods for monitoring provided by AsyncTaks like onPreExecute,onProgressUpdate, onCancelled etc. I know there might be another way to implement it.
Native Java Threads - I know is good to make use of this tool when my task is not related to any view in android at all, and do not need to be monitored (example: removing/adding data from remote database, and the response might affect just persistence elements that will not be displayed like configuration preferences)
IntentService - When i want to do a one time task in a queueprocessor fashion way, but unliked a native thread, here i would like to have some application context in order to maybe bind an activity etc...
Regards!
I'm developing an app in which I pretend to invoke a REST service for typical CRUD operations. Since I want to separate the requests processing from the UI thread, I'm planning to use an AsyncTask to do the separate work. However, my question here is: how should I desing my AsyncTask(s) model? Should I use one AsyncTask for all CRUD operations (is this even feasible?), or use i.e. 4 AsyncTasks (create, delete, update, retrieve)?
Thanks in advance
I would go with a ContentProvider instead of using AsyncTask.
According to this thread:
https://groups.google.com/forum/?fromgroups#!topic/android-developers/8M0RTFfO7-M%5B1-25%5D
on Android 4 AsyncTasks will be sequential.
So, for that reason alone your solution may be less than optimal.
But, ContentProvider just makes more sense for what you are trying to do, as what happens behind the CRUD calls the user doesn't care. You may want to run this on a separate thread though, as being on the UI thread for too long is bad.
It is really up to you, and perhaps, the REST service which you are consuming.
Some things to consider:
Is the service general enough that it would be easy to do everything in a with a single AsyncTask?
Will your code be easier to read and understand if you do things with a single AsyncTask? I would tend to think that it would be easier to read if you did one AsyncTask for each operation. (ie, CreateTask, UpdateTask...)
Will I get the reusability that I am after with my choice (whatever it is)?
Personally, I would create 4 distinct AsyncTask's, and any reusable code I might put in a base class, but again, it is really up to you for what is going to work best for you.
Personally, I use the Loader framework, available with the compatibility library. I have a subclass of AsyncTaskLoader for each of the CRUD operations, and it works really well!
I guess if you prefer to avoid having lots of classes you could use the same task (i.e. the create and update could technically fit in the same task) - when you subclass your AsyncTaskLoader create a setParameters(...) method which you can call when you create the loader in onCreateLoader().
It might help to read the above after you've reviewed the Loader documentation.