Android: Starting intent service within fragments - android

I have multiple fragments within an activity. Every fragment has to display some data that is fetched from the server using REST. I have been implementing IntentService with a corresponding receiver for REST requests. Right now I am able to do this by making fragments as inner class within the activity.
The problem I have with inner class is, on orientation change, an error is thrown like "cannot instantiate fragment, no empty constructor". For this problem, on search I found answers like either make the inner class static or create a standalone public class for Fragment. I still don't understand why would this happen on orientation change.
Now if I take the approach of creating a separate standalone class for Fragment, I will have to pass the activity object around to do startService and registerReceiver. And I do not want to use AsyncTask for this, as in my app I perform multiple REST requests within a single fragment and IntentService allows a broadcast to be sent after every request so that I do not have to wait until all the requests are finished to start loading the screen. And I feel it is not ok to pass activity object to a fragment. Shouldn't the fragment be as loosely coupled as possible with the activity so that same fragment can be used within multiple activities? If yes, what would be the best approach in resolving this?

Related

How to open multiple instances of the same fragment but with different data, one after the other?

I made several api calls from a model class of an Activity and upon receiving responses from each of them, I need to feed the data to a Fragment one after the other by invoking multiple instances of the same fragment.
Ideally, the next fragment will only be fed with data after the previous Fragment has exited (by response from a listener).
I have looked everywhere and couldn't find a solution to this problem. I have tried using AsyncTask with a CountDownLatch to block the next api response before getting an action response from the initial Fragment but after it only invoked one Fragment (I know how many fragments I should be creating) and back to normal Activity view.
Any thoughts on how to deal with this problem?
There are 2 ways for this
Create a constructor to the fragment where you pass the data when you create instances.
mFragment1 = new xFragment(dataA);
mFragment2 = new xFragment(dataB)
To use Interface and Implementation to pass data from Activity to. Check the link below
https://developer.android.com/training/basics/fragments/communicating.html

How to pass object between unrelated activates?

I need to pass an object between 2 activities that have no connection between them (meaning, neither of them calls the other).
My Main_activity extends TabActivity. I have 2 tabs : CurrencyList (extends ListActivity implements OnItemSelectedListener) and CurrencyCalculator extends Activity.
I also have class currencyData that saves data about different currencies.
In the CurrencyList activity I created a new currencyData object and initiate it with data.
How can I pass it also to the CurrencyCalculator activity?
2 quick ways:
1. use an static method in your activity to retrieve current ticket id
2. Design and implement an interface and register the fragments as listeners from the activity
Static Method is preferable for large data.
If there is absolutely no connection between them, then one method of accessing data in different Activity classes would be to declare the data members as static class members. Keep in mind that static objects from Activities persist even after you destroy the activity and Android keeps this around for some time even after the you leave the application.
These might not be the easiest ways (just some alternate approaches to the two answers given). You can use a Handler or a BroadcastReceiver to pass the data to the other activity through an intent.
Note
that your object would have to implement either Serializable or
Parcelable if you want to pass it through an intent. I have used
Serializable before and as long as your object does not have any
nested custom objects, you actually have to do no additional work.
Also the assumption is that the receiving activity is alive and is
able to receive the broadcast and/or message.
Another approach would be to write the object to a file (again it would need to be serializable) and read it back in the other activity.

Android Service > Activity > Fragment with ViewPager

First, I'd to state that I've been searching for a solution for this problem for three days now, that may means either I'm not asking the right question or not using a good approach. If any, please guide me in the right direction.
This is the scenario: I've an Activity and a bound Service. The Service holds some data and processes it as necessary while posting a persistent (ongoing) notification with some information. The Activity has three Fragments inside a ViewPager that displays the data processed by the Service.
The Fragments are a List Fragment, that shows the active data entries available, a Details Fragment that displays the details for each data and a Parameters Fragment where the user can modify how the data is processed.
[Service] <-> ([Activity] -> [ViewPager([List], [Details], [Parameters])])
Everything works just fine. My Activity binds to the Service, the ViewPager is created after and then the Fragments fetch information trough an Interface.
Here comes the fun part... Screen Rotation!
As the Service binds asynchronously, when the user rotates the screen the Fragments no longer have the data because the Activity is bounding the service while they're already present and not recreated thanks to the ViewPager.
I've been trying to figure this out but it seems that I don't have the knowledge to solve it. I've tried making static references to the fragments, setting them up before the service is rebound but I can't get a stable solution.
I'd be using android:configChanges in my manifest but there are different layouts for each orientation.
Again, if I'm using a bad approach, please, guide me!
Difficult to suggest when I don't know your code but thinking out loud....
Can you have a "worker fragment" that is never displayed (i.e headless) and has setRetainInstance(true) set so it does not lose any state you have set.
Your worker fragment would bind to the service instead of the activity and maintain a reference to it.
If you need to communicate with your Activity, you can do this with callbacks.
Your other fragments could communicate with the worker instead of the Activity.
This process would basically make the activity little more than a shell into which the rest of your components are hosted. Rotation would lose nothing because all data is held in the retained fragment.
During the screen rotation process the activity is completely destroyed and use of android:congfigChange is discouraged. but what you can do is you can override saveInstanceState(bundle) method in which you can save the data present in your activity at the time it is destroyed by the system in response to the screen rotation. and later receive it as the system passes the bundle to the activities onCreate(bundle) method or get it from the restoreInstanceState(Bundle) method.

How to make a core of activity on android?

I am new to Android development. After learning from many tutorials I got many Activities and many Fragments. How can I make a core engine to check what Activity is running and what Fragment is showing on a container?
Assume that I have:
Acivity01, Activity02, ... , Activity10
Fragment01, Fragment02, ... , Fragment10
I want to make a class that filters the Activity where Activity is on runtime and what Fragment is embeded to that activity.
How can I do this?
If I understand you correctly, you may want to store some references within your Application class to an Activity and to Fragment instance(-s), which are currently in foreground (by this I mean that user can instantly interact with Activity/Fragment).
As for Activity
Create some Activity field in your Application class and getter/setter methods for it (e.g., setCurrentActivity(), getCurrentActivity()). Then call setCurrentActivity() from onResume() method for each of your Activity instances. Don't forget to call setCurrentActivity, supplying null reference to ir in order to properly handle a case, when there are no foreground activities, but application is stll working.
As for Fragment
The general idea is similar to the first item, but there can be more than one Fragment instance in foreground state at time. So you need to store something like List, where you add your resumed fragments and remove paused.
You may also want to implement something similar for dialogs, for example. Then use the same strategy. Hope it will help.

Is this the best way to implement AsyncTask? Or are there better ways?

I am trying to write a AsyncTask generic package. Till now, what I've done is call one activity from another send the instance in the Intent to that Activity. This activity is part of the AsyncTask which calls the AsyncLoader.execute() file. I am doing this so that I don't lose any data that the parent Activity sets on the layout.
The other way to do it would be to call the Intent and return the data from the AsyncActivity to the parent Activity. But, both of these methods are slower than implementing the AsyncTask in the parent activity.
But, that clutters up the code. Thus, is there a better way of implementing it?
It sounds like your tight-coupling between the activity and the AsyncTask is causing you issues that you're trying to overcome with a weird workaround.
In my experience the best way to design activities that need an AsyncTask is:
Keep your AsyncTask out of your activity, i.e. make a separate class
that extends AsyncTask. This allows you to reuse the AsyncTask
between multiple activities and make it easier to test.
If you need to return data back to your activity, use the listener and implement the listener on your activity. Then pass your listener to a class that creates the AsyncTask.
Passing of data between intents should be kept to a minimum, if you need to reuse the same AsyncTask from a separate activity you should follow the steps above and execute the task again. If you're going to be calling this through the lifecycle of the app, then consider using a service instead.

Categories

Resources