My problem seemed simple to me, but apparently it isn't.
I got a core class that is able to calculate a complex result depending on parameters entered by a user. Up to now I showed the result as a ListView and for the detail view, I used a sliding panel - so everything is neat within one activity A.
But now, I wanted to get rid of the sliding design and "simply" use a master/detail flow so I could show two fragments next to each other on tablets and separately on a mobile phone.
Well, I did not want to redesign the whole app for that, but basically: how do I get the detail information to my different activity B???
I know that through an Intent I can only send Parcelable (or serializable) data, but that is far to complex for essentially int-array-type of data! All the converting to and re-constructing from the Intent - that is just a pain!
Of course, I also do not need a database or similar complicated stuff - no SharedPrefs, please, that is all at least as complex as implementing the Parcelable!
Basically, I thought of two approaches, but they all ... stink ... kind of:
a) store the calculated data within the application class - problem: the app might get destroyed and restarted just for re-displaying activity B. Then there wouldn't be anything left in the app object!
b) implement a content provider that does the calculation and caching the result there. Hmm. The cursor again is way to complex to transfer the simple result. And: for how long should I cache the result in the ContentProvider?
I feel this is all a mess. :-(
Any ideas?
The Intent approach is by far the simplest one.
Talking about a Master/Detail flow, usually that means passing one id, this is few information and easily reconstructed from A to B (activity).
Don't use A for exactly the reason you mentioned, and B wow! too much work =)
I really think either use an Intent or use shared Prefs they are by far the least code demanding options.
Have you been able to create the behavior of the app getting destroyed and everything being deleted? I've been developing an app doing some things along the same lines and I have just been using public static variables to store things in the activity that they are created in. That way they are accessible from other activities. Not necessarily the most elegant way of doing things but it's working for me just fine.
oh man its not mess:)
did you aware of Design patterns if yes then you can use singleton pattern where you can store data for your next activity
public class mySingleton
{
mySingleton instance;
yourvariable1;
yourvariable2;
yourvariable3;
yourobject1;
yourobject2;
public static mySingleton getSingletonInstance()
{
if(instance==null)
{
instance=new mySingleton();
}
return instance;
}
}
by this you can save your data till your any activity is running or you may say untill your application is in system memory
but if you want to close application and persist data then make a background service there you can save data your applications activities will destroy but the service will contain the variables and data
hope it will solve your problem
Related
Most the app so far I had created, I fetch the data from Network and store it in a singleton class to share data between Activities, when I'm done with those data, I usually clear those setting it to NULL, its work perfectly well
My Question is which approach is better ??
Use parcelable
Writing in database and Query for it
Singleton classes
When exactly we need to use Loaders ?? Why we can't share the data through Loaders ??
If question is repeated ... Please ignore ??
Answer to first part
Parcelable:
The best way to pass data between Activitys or Fragments is by using Parcelable objects. It is said to be more optimised than Serializable. There are couple of libraries/plugins which can help you create Parcelable objects. Lately I was referred to Parceler, created by John Carl. However, I personally use Android Parcelable code generator by Michal Charmas, plugin for IntelliJ IDEA and Android Studio.
DataBase or SharedPreferences:
Using DataBase or SharedPreferences to pass data between Activitys or Fragments sounds weird, and since they are not designed to be used this way, it will only create a mess.
Singletons:
Read this very informative post Singletons are Pathological Liars.
Conclusion:
I recommend Parcelable or if you want to be real lazy then go for Serializable (it's not terrible but it's not great either, according to most).
Don't mess up your code by using singletons, DataBases, static fields, etc. They will come back and haunt you.
Answer to second part:
When exactly we need to use Loaders
Loaders, which will be AsyncTaskLoader when you use, are basically used for situations where we want to retrieve data from the server (via web API), or doing something in background. It is similar to using Thread or AsyncTask but is very powerful as it isn't destroyed on screen rotation, unlike those two.
You should read How to Use Loaders in Android and Alex Lockwood's posts on Loaders (this is a series of 4 posts. Very detailed and great).
It all depends on the way you want to use the data.If you want to use the data in future, as in after the application is killed and re launched you should save it in a database.
I would prefer parcelable over a singleton as I don't have to bother about clear the data.
According to the Documentation we generally use loaders to load data asynchronously and to monitor a the data source for change. To my understanding you aren't doing either of them, hence loaders are not required in this case.
1.Database: If you are going to use the network data in future or you are going to do some query operation to perform filtration according to requirement,it is preferable to go with db.
2.Singleton Class: Most of the developer use this because it is more efficient,the values can be changed and retrieve easily with the help of getters and setters.
Here is a very cool way of passing data to another activity I read this somewhere else on Stackoverflow and always use it now. It may not fit your use-case but it sounds like it will.
For example, say you want to pass a parcelable "DataModel" from ActivityA to ActivityB.
Inside ActivityB create a public static method called 'start' like this.
private static final String DATAMODEL_KEY = "datamodel_key";
public static void start(Context context, DataModel dataModel) {
Intent intent = new Intent(context, ActivityB.class);
intent.putExtra(DATAMODEL_KEY, dataModel);
context.startActivity(intent);
}
To start ActivityB simply call the 'start' method above like this
ActivityB.start(this, datamodel);
Use 'this' if called from an activity, or 'getActivity()' from with a fragment.
This will contain the code for starting ActivityB inside ActivityB, like the private static final DATAMODEL_KEY field and such. To answer your question though, go with option 1 and use parcelables and try out the code I posted above to help with starting the Activity with the data.
For my current project, I will be using this SlidingUpPanel library.
The sliding up panel will host a fragment that will contain application/global level information. This panel will be in every activity in my application. This will be very similar to the way Google Play music works.
My question is, what is the best way to persist the sliding up panel fragment throughout my application? I see myself going about this in two ways...
Storing the fragment inside the Application class and loading it at the start of every activity (somehow, not even sure if this is a possibility).
Storing the data that it will display in the Application class & loading a new instance of the fragment, passing in the persisted data.
Which one of these two ways would be the best? Is 1. even possible? Are there any coding landmines with these approaches?
Storing a fragment to persist throughout the application lifecycle would be pretty unorthodox, mainly because the fragment class should be able to follow it's normal lifecycle events (in this case, mainly onPause and onResume) instead of being stuck somewhere in the application class.
It is definitely common practice to store the data and load it each time you display the fragment. If you want to enable some sort of cacheing or singleton pattern to access the data, it should most likely be with another object that the fragment can access but is not a member within the fragment.
There is a good video from google about leaking views and it touches briefly on the pitfalls of doing some similar to what you're proposing in bullet #1.
I think the structure of your app looks like it should be a single activity where that bar is in it, then the main content is a Fragment that you replace and use addToBackStack on in order to maintain the use of the back button. Otherwise, you are going to have a lot of repeated code with solution 2 (which means a lot of repeated work in the case of bugs etc., not very maintainable), or leak views using solution 1.
More info on providing a proper back implementation
Hope you guys can clarify something for me.
I've been using Android for about 6 months now and I'm still confused about the best way to communicate between Activity and Fragments. I've already read the the info on the android developer site.
Fragment to Activity
Right now I know with 100% absolute certainty that an interface is the best way to communicate from Fragment to Activity. I.e. creating an interface in your Fragment and letting your Activity implement it. This way you can call the method from your interface inside your Fragment and have it handled by the Activity (which implements the interface).
Activity to Fragment
Here's were I'm not sure. The android developer site says that in order to communicate with a Fragment you have to put your objects in a Bundle.
Bundle bundle = new Bundle();
bundle.putInt(SOME_IDENTIFIER, myInt);
Now I've been know to use a Singleton class every now and then when I have quite some functionality that I can separate. Say I have a Singleton called PersistenceService where I handle all of the persistence related stuff, e.g. saving something in the SharedPreferences. The PersistenceService will then hold methods like putMyString(String key, String myString) or putSomeObject(String key, SomeObject someObj). This way a class doesn't have to handle persistence itself but can just call the PersistenceService to do it.
Now say I have to update something in my Fragment, a TextView or something.
This is what I do:
String myString = PersistenceService.getInstance(getActivity()).getMyString(someKey);
textView.setText(myString);
I pass in a context (getActivity()) because I need it to get the SharedPreferences.
Now my actual question is:
Do I retrieve my data in the Activity and pass it to the desired Fragment through its Bundle? Or do I simply reference my Singleton right in my Fragment and access the data there directly.
I'm not stuck or anything, but I'd like to know what you guys would recommend.
Any advice, remarks, info etc. is greatly appreciated.
This is a very broad question, and as the pragmatic thinking and learning book says, the answer to most questions in software is "It all depends!".
And it really does, it really all depends, there's no hard rule in software, "always" and "never" are very powerful words that shouldn't be used in software, so, saying always go for "Bundle" info or Never go for a Singleton is a little bit stupid specifically in software, so, instead of telling you exactly what to use, ask your self what would fit better in your needs taking on count things like, scalability, extensibility manageability, etc. For example:
If you go for Bundle, you give some flexibility to your fragment, you are creating some kind of independent component ready to work with whatever information you provide, on the other hand, if you know that you need that fragment only in that place, and the information you will pass is somehow complex(can't be passed using a bundle), why complicating so much? Just go for the Singleton if it does the job simple and clean.
I hope my point is well explained here, there's no hard rules for one way or another, just be as diligent as possible and don't go one way or another just because of laziness or negligence, instead be analyst if it's worth going one way or another based on your needs, and always take on count that not because you went that way this time it will be true for ALL your scenarios.
Hope it Helps!
Regards!
I use bundle when I want send data from fragment to fragment (from fragment to activity by interface, from activity to fragment by bundle).
If data is used in all fragments singleton is the best way, sometime I use also a istance of data objcet in activity that I manipulate in fragment by public methods of activity but I don't think that this is a best pratic.
Please understand that 2 fragments can’t directly communicate with each other, They will need help of the activity under the context of which they are created. Using an interface :).
Implement the interface in a fragment
interface StartCommunication
Define the interface in the activity whose context fragment is using
public class MainActivity extends Activity implements
SendFragment.StartCommunication
This is more of a question where I'm trying to see if my thinking is correct before I start coding something that winds up not working. Let me see if I can explain what I'm trying to do first. My main issue is wanting to know if I'm on the right track or not.
I'm creating a game using the page viewer and fragments so I can have a tabbed layout. That's not a problem. Where I'm getting confused and turned around is that I have multiple activities, each handling a different part of the game so that I avoid having too much on the screen at any one time. I had wanted to have all of the game methods in a single class and have each activity pull from it. Can I do so if the class is private? I assume if I had a GAME class for example that I would have to instantiate a particular version of it somewhere but if I did, how can I be sure that everything is pulling from that same instance?
Another approach I had thought of was basically just making one game class that did everything and then just spit out the variable values to the various activities as needed which would then update the UI. Would that be a better approach? I think if I do it this way I can avoid having to pass data directly from one activity to the next. I can just have them all pull whatever values they need directly from the class.
Does any of this make any sense or am I way out in left field somewhere? Any direction to go in to start would be helpful as I've been going around for days trying to chart some kind of course.
It sounds like you want to put all your game logic into a Game class and have all of your Activities access that single Game instance. The answer is yes, that's probably the right approach and a simpler approach then trying to get your Activities to pass data around via Intents.
You can use a singleton pattern to get access to the same instance everywhere. (Something like this)
public class Game {
private static final Game INSTANCE = new Game();
private Game() {}
public static Game getInstance() {
return INSTANCE;
}
}
Or if you're using a dependency injection framework like Dagger, you can just mark the Game provider as providing a singleton. (If you don't know what this is, just use the singleton pattern above for now)
I am currently working on an app which takes a number of user entries. I want to have each EditText field on its own page, and instead of having a seperate activity for each entry, I wanted instead to call the same activity again. Is this possible, and if so, is it a feasible solution? Thanks.
It is possible but I don't think it is the way to go. Basically if the next input is a separate action then it deserves its own activity.
That is the way you are supposed to do it.
You could store the gathered values either in the Application class as a temporary storage or you can save it using SharedPreference. However if it is only temporary data I advice you to use the Application class rather than writing it to a file.
I would think that if your UI doesn't change (significantly) between views, then reusing your activity and displaying different data seems fine to me (I do this myself).
I keep an object on the Application class that contains a list of the sub-objects (Inputs in your case).
On the top level object, I keep the index of the current index.
This works very well, does not leak memory and is very fast to render as I swipe through my pages.