Activity and fragment responsibilities in network communication (robospice) - android

I am creating apps using Robospice library. It is great choice to handle internet connections, because core of the library is based on Android Service, so our connections are not tied to the Activity life-cycle.
We are creating our requests and executing them with spice manager which in turn is instantiated in each activity (Base Activity inheritance) , I don't is it right way to place creating of manage object here, if there is better way to do this, please let me know.
public class BaseActivity extends AppCompatActivity implements ActivityController, SpiceManagerProvider {
private SpiceManager mSpiceManager = new SpiceManager(MyRobospiceService.class);
I have been creating request (robospice requests) exactly where I need them in fragments and activities. But now I thought a little bit about this. Maybe it is better to separate request handling only in activities. And just listening for button clicks or whatever from fragments in activity with callback methods or some other inter component communication. And than in activity make request, handle it. But in this case if I need to get data back in fragment I have to send it back from activity to the fragment. So it seems a lot of redundant communications.
All in all I wan't to get advice from more experienced developers about separation of responsibilities, should I handle request in only one component (like activity) or I can make and handle requests anywhere I need this.
Thanks everyone in advance.

Using a single SpiceManager per Activity and sharing it between Fragments is what I have successfully done in the past. You have to, unfortunately, check if the Activity is still resumed in this case for every response listener.
To be specific, you need to be sure that you will not update a stopped or destroyed UI.
See related FAQ question for more details.
The second paragraph there mentions the the other approach of having a SpiceManager per Fragment, so that should be a viable option for you as well. We noticed some overhead while creating SpiceManagers (this only hurts when there are many Fragments) and therefore abandoned it for our use.

Related

Should I make http requests in Activity, then pass data to Fragment? Or make requests directly in Fragment?

I have application where I have Activity with few Fragments. In that state it's easy. In Activity, using retrofit I make request to REST API, get data then pass it to Fragments using bundle. (Passing list of my objects using bundle was a little pain, but manageable)
Problem starts when I want refresh data in Fragment every x seconds. With described solution I'd have to recreate Fragment with every request, which is ... stupid.
So I have 2 ideas:
make all requests to REST API in Fragment. But I have no idea if it's considered as good solution.
make all requests in Activity and exchange data using EventBus library. (http://greenrobot.org/eventbus/)
Can you please tell me if one of those ideas is good, or should I do something completely different? Or can you tell me pros and cons of different approaches?
Thanks a lot for answers!
Make your fragments loosely coupled with activity so that it can be used with other activities. According to Google -
In order to reuse the Fragment UI components, you should build each as a completely self-contained, modular component that defines its own layout and behavior. Once you have defined these reusable Fragments, you can associate them with an Activity and connect them with the application logic to realize the overall composite UI.
Read more - https://developer.android.com/training/basics/fragments/communicating.html?hl=ru
It is better to request network data from Fragment. Also if you have any dependency of the data in your activity which is received from the network call then you can also use callbacks to send that data back to activity
It's better to have service for HTTP calls. You can make async calls from service, and implement listener interface at your activity or fragment. Than that listener can interact with view.
I usually agree with MmtBkn, but since you use Retrofit, I think it is at least not a bad practice to perform HTTP requests from the UI class. And in my opinion you should make these requests from the Fragment, because it contains the views where the loaded content will be displayed. If you think about placing the Fragment in another Activity, you would end up with duplicate code that performs the HTTP request and sends the data to the Fragment via event bus.

What role an Android Service should play in the MVP pattern?

I am developing an Android app that does Human Activity Recognition.
It basically works like that - Service constantly reads the accelerator data and stores the recognized activity (i.e. Walking, running) in a database. The user can see all of the recognized activities in an ListView in activity (accesses the database). Every User table in the database has a pa_goal (physical activity goal) field which the Service reads from the database and does some checks.
The user, of course, can change this goal from an activity. Since I will be implementing the MVP architectural pattern.
I am unsure where to put the Service? It surely isn't View. Any advice?
In a clean architecture, which is what I am assuming you are using MVP for, there is the idea of separating the framework from the business logic. This is essentially what a normal presenter allows you to do.
In this case its not a view you are dealing with but the principle is similar. You don't want all your business or application logic mixed in the Android code when you can separate them out for nicer, more single responsibility classes. So I would say that while it isn't a view you should still have a presenter type class (probably better to be called controller or manager maybe).
This class would be a POJO that controls how your service behaves which is easily testable with standard junit tests and service mocks. This class and the service could then be put into its own feature package and interact with the back end models the same way as your presenters.
So, in summary, the role is of another feature of your app that sites alongside the other features (which are usually just views in my experience).
Hope that helps
This article helped me in a similar situation, although may not be exactly yours, the idea is the same:
https://android.jlelse.eu/android-bound-services-and-mvp-12ca9f70c7c7
Basically, the author works around the fact that a bound service is tightly coupled to an activity, and it adds extra lifecycle calls to it.
I am in the same situation. Finally I decided to do something like this:
Activities or Fragments are out of scope, they do not know anything about MVP BUT i am going to use an event bus like Otto to send signals/events, So:
My classes which extends some kind of Presenter know nothing about Android Context but they will have an MvpView interface, with only onAttachPresenter and onDetachPresenter.
The class which extends Service will have a Presenter attribute and implements some MvpView interface with onSucess, onError, onStart, onComplete or something like that and same events for Otto (onSucessEvent, onErrorEvent, onStartEvent, onCompleteEvent).
So when I need to do something the Activity or Fragment will start the service, the service will "start" or talk with the Presenter and when the presenter finish with success will call to mvpView.onSuccess() and store the info inside a local DB with SQLite (storeIO maybe) and finally the Service will invoke Otto and pass the signal (without any data on it), probably onComplete.
Finally the signal will be catched by my UI (fragment maybe) and retrieve all the info inside a DB in SQLite.
So when the onSucess happens the UI will show the latest and best data BUT when onError happens will (at least) show some info (or not if you want) saying to the user "there was a problem but at least you can see something", bot onSuccess and onError will call onComplete after all.
Do not know if this is the best solution but in this case I think I am not going to deal with Activities or Fragments lifecycle and do not care about onSaveInstance and restore data when the user rotates the device. It will always fetch the latest data inside DB, and if something happens (no internet connection) you can at least show something when you receive the onComplete Signal.
Some facts I am still thinking:
The Presenter won't be a singleton class
Presenter knows nothing about Context but yes with MyApplication class
What happens if for one screen (Fragment) you have differents service with differents onSuccessEvents? Simply use some kind of action as an ID, to identify them.
Never make the Activity Fragment implements the MvpView, you will have to deal with the lifecycle.

Is it a good idea for a Fragment to delegate all navigation control to Activity?

Inspired by the Android developer guide I am trying to write code in which all fragments are self-contained (in terms of network/logic) and any actions they perform (click/tap) which should result in launching a new activity/fragment would be delegated to the activity (through callback).
To begin with, it seemed right. But now , when I have fragments which have more than 1 such widgets (which need the fragment to navigate to a new screen), it seems like a mess. I either need to write multiple callbacks or do some switch-case logic in Activity for different actions done on a fragment.
If this design sounds bad, what are the scenarios where implementing callbacks (as suggested by the guide) would be a good idea ?
I don't know how you are implementing these callbacks.
One approach to this problem is to use the contract pattern:
The fragment defines a Contract interface, that any hosting activity must implement
When the fragment wants to pass control to the activity, it calls a method on that interface
Jake Wharton has the canonical implementation of this in a GitHub gist. The only piece that is not shown is that the activity that hosts his MyCoolFragment needs to implement the MyCoolFragment.Contract interface.
This assumes that each fragment has distinct events to raise to the activity and therefore needs its own interface. If you have several fragments with common characteristics, you could standardize on a single interface, rather than duplicating the Contract everywhere.
There are other approaches (e.g., the comment on the gist suggesting using a message bus), but for simple fragment->activity communication, the contract pattern should have the least overhead, both in terms of coding and runtime implementation.
Your general approach, though, of delegating work to the activity where that work may result in changes to another fragment, is definitely a good one. It makes it that much easier to handle the cases where the fragments are not on the screen at the same time, perhaps hosted by different activities, as you handle different screen setups (phone vs. tablet, single screen vs. displaying content on a connected TV, etc.).

General structure of android app

Im searching to make a simple android app that can do two things:
Show incomming bluetooth data on a graph
Send user defined data back using a textbox and a button
I'm using the navigation drawer, and loosely based on a tutorial, I've set up a GUI with two fragments, each running their own activity.
My question is now, where would I put all the bluetooth related stuff? Each fragment must be able to both send and receive data, will I have to implement the bluetooth connection in each activity? Can I implement it in one activity (e.g. mainactivity) and reach it from the other activities? Is there a better way to do this (i.e. two fragments from one activity)?
Update:
Maybe I'm confusing myself a bit. What I currently have is a main-activity, (extends Activity) that starts one of two fragments (extends fragment) by calling
fragmentManager.beginTransaction().replace(R.id.container,
MyFragment.newInstance()).commit()
So this is actually one activity only, I guess. Question is still, will I put bluetooth related stuff in the mainActivity, or in the fragment-classes that are created. Do I even need the fragment-classes, or can the xml-fragment layouts be handled from within the mainActivity instead?
You probably want to implement a Service, which you can reach from any of your activities or fragments.
Alternatively, you can have a singleton object somewhere which manages this connection, but this can create more complicated lifecycle issues, so I would recommend simply using a service.

Android: Intended use of fragments with services, dialogs etc

I've been creating android apps for a few months now and I'm having trouble with the intended use of Fragments.
Fragments are supposed to be reusable UI components but how far do you make them stand alone?
One of the Fragments I've created is a ListFragment of downloadable videos. At the moment I've implemented all the methods inside the Fragment with little or none of the methods calling the host Activity. The Fragment calls the Activity for a few minor things but everything like downloading files and finding them on external storage is done by the Fragment.
90% of the time I find it's the easiest way of implementing it but there's some times it just doesn't work.
An example is a confirmation dialog for deleting a video in my ListFragment. The dialog is a DialogFragment so is attached to the Activity but all the UI update and deletion methods are inside the ListFragment. So I end up with the DialogFragment calling the Activity just to call the ListFragment.
Another example is binding to a Service. Do I bind the Activity to the Service or just the Fragment? The Activity has no use for the Service but is a Fragment supposed to be doing all the work of starting and maintaining a Service? If not it means all the Fragments calls to the Service have to go through the Activity so the Fragment is no longer stand alone.
I'm wondering if I'm taking the stand alone idea too far, is a Fragment instead supposed to be minimally self-contained and actually rely on the Activity hosting it for all the heavy lifting?
Thanks for any help.
A very interesting question!
I usually try to keep my fragments as isolated as possible. That means I usually don't let them know about anything around them except for their own activity. It's then the activity's role (if you ask me) to provide what-ever-is-needed to the fragment.
In practice this means that my fragments never own their own content, like a content provider or a custom DAO. The activity (or - God forbid - the application) owns it and then provides only a subset of the data, like a cursor, a domain object or an adapter, to the fragment.
This also means that when a fragment modifies an item it has to ask the activity to persist the changes. Or if an item is to be deleted, the fragment has to ask the activity to show the corresponding UI for that operation (yes, it's technically possible to let a fragment show another fragment, but I usually try to avoid it as far as possible).
When it comes to services and binding to them I really don't know what to suggest as it really depends on the service and what it's doing. If you're downloading new content from the internet in your service, then it seems rectified to let the activity handle the binding (as it is the activity that needs to save the data, according to previous discussion). If you, on the other hand, are calculating something specific, based on your isolated data (e.g. decrypting a file or so), then it might make sence to let the fragment handle that part.
In an even greater perspective one soon realizes that a setup, such as described above, will give birth to quite some callback interfaces as each fragment needs to establish a contract to its activity. Hence, for smaller projects it sometimes happens that I override my very own fragment-pardigms.
I also can't help noticing that when using fragments, my applications tend to be very MVC oriented in their architecture. I leave it to you and any future readers to decide wether it's a good or bad thing ;-)
Cheers

Categories

Resources