If I put my service and activity in the same package, Can I exchange data between them using some global variables? I want optimized performance, so, global variables idea seems good but is it possible? If not, what is the best option. If intents is the way to go, then would the performance be good enough? BTW, the service has a big hashMap (may be multiple). This map needs to be accessed by the activity?
Thanks,
Rahul.
I know if you have multiple activities in a project, it's possible to start up one activity with certain args.
http://getablogger.blogspot.com/2008/01/android-pass-data-to-activity.html
This might not be what you're looking for though.
Don't use global variables. They are volatile due to the activity lifecycle, so you run the risk of having them garbage collected.
You can accomplish what you want using ResultReceivers. Here's a nice tutorial:
http://lalit3686.blogspot.com.br/2012/06/how-to-update-activity-from-service.html
Related
It seems to me that if you have some state or data in android that you want to access from different activities (but don't want to persist) you need a singleton. Is this correct or are there other ways to design an application?
It is not that I have a problem with singletons. I am just wondering because this is so radically different from normal desktop application development.
What you said is definitely not correct and there are other ways to design an Android app.
Actually, for Android development, Singletons should be avoided or used sparingly and should not be used as the first or only solution. It should especially not be used to carelessly share data or state across Activities.
If you find your app requiring the use of Singletons for everything, then chances are... you're in need of a redesign for your app.
When using Singletons, there are actually a few things to keep in mind:
They typically live throughout the entire lifecycle of the App until they're closed by the system closing your app
Improperly created Singletons can easily leak memory
Improperly designed Singletons and excessive use of Singletons can use up a lot of unneeded memory
They're hard to use for testing
Overall, when using Singletons, you really need to think about if there's a sufficient need for that part of your app to be a Singleton.
For most situations, the answer is no. In the cases you mentioned, such as accessing state or data between Activities, it's a yes and no.
It's a yes because the need to access data might warrant the use of a Singleton. It's a no because the need to access the state of the app shouldn't.
Your use of the word 'state' is a quite unclear, but Activities should really be self-managed, since the state of an Activity shouldn't interfere with the state of another Activity. If it does, there are better ways to send that information to the Activity (such as using Intent extras) rather than creating a Singleton that is accessible for everything and existing for longer than it should.
There really is very few reasons to warrant a need for a Singleton.
In my experience, there are only two reasons that might allow for the use of a Singleton:
The real need for a single instance to exist
The Singleton is used very often and it's expensive to constantly create it, but there won't be any major side effects to keep it in memory.
For example, an SQLite Database is commonly used as a Singleton because a single synchronized instance of the database can help prevent more than one Activity or Service from reading/writing to the database. This helps prevent situations such as one object writing new data, while another object reads old data before the new data is written. Or the simple situation of two objects writing different data to the same field at the same time.
Additionally, an SQLite Database is also accessed very often by apps, so it doesn't make much sense to constantly open a database, fetch some data, close the database, open a database, write some data, close the database, and repeat.
I've seen developers use Singletons for a lot of situations, and most of them for really bad reasons.
The Good:
Databases
SharedPreferences (the app needs to access preferences way more often than normal)
Logging system
The Bad:
I saw a developer load up a large amount of Drawables and stored it in a Singleton upon starting his app... just so he could quickly use those drawables everywhere.
I saw some developers using Singletons to hold a list of created Activities, so they could access those Activities methods and views... (dead)
I've seen more bad stories, but I can't recall them now.
Also, keep in mind that even though I said things like Databases are a good idea to be used as a Singleton, I only meant it has the needs to warrant the use of a Singleton. A database doesn't need to be a singleton and there are other solutions available that might fit your app better.
So always think about whether there's a need for you to use a Singleton.
In your case, does the state/data you need to access by other Activities really need to stay alive for the duration of the app and can it be solved through solutions like: SharedPreferences, Intent extras, Callback Interfaces, Databases, static classes/fields/methods, and etc.
If you've thought out your app well and really think a Singleton will benefit your app best, then use it. Don't forget to use an Application Context instead of the Activity's Context, because the Singleton will definitely outlive your Activity and you don't want memory leak issues.
When passing data around in Android (between Activities, for example), it seems that the primary accepted method is to use Bundles and Parcelables. The problem with this approach is that it serializes all the data, which is inefficient. I'm wondering - is there way to pass around references rather than the data itself for efficiency?
This may be less efficient (though should not be a big impact in most cases) but avoids keeping a references to object between activities. That helps to keep the architecture cleaner and with less prone to memory leaks.
You can use Application class, static helper classes, singletons or services in some cases to help you but make sure you know what you're doing with them.
I would say your best approach would be to make all data model objects parceleble, and make all activities extend a base class and use a wrapper or a helper method to pass your data model objects between activities.
I use this approach in all my applications and thus far it has been very helpful and minimizes the number of references used between activities and fragments.
There are a number of techniques you can employ, it all depends on what you are trying to achieve, for example you can use a singleton to keep a reference alive, or you may (although you really shouldn't) use a static reference. In the end it all comes down to what kind of data are you trying to pass around.
Remember that sometimes is better to rebuild an object, than it is to keep it alive until (if it ever happens) the garbage collector clears it.
I like to use the singleton design pattern.
http://en.wikipedia.org/wiki/Singleton_pattern
I'm currently attempting to convert my existing Android app to using Fragments. The main work that my activity does can sometimes take a while, so I implemented some Threads to act as callback handlers - I was led to believe this is best practice to use these and a progress dialog.
Hopefully that makes sense.
My question is: should I move those inner classes to my Fragment class, or keep them in my Activity class?
That depends how many fragments you have and what you're trying to do with those threads. While there is no general rule, here are two things to consider in making your decision.
(1) If you're doing something like downloading information that's going to be used in multiple fragments (say in a ViewPager or Tab set up) it might make sense to have the callbacks in your FragmentActivity this way you can easly distribute that information to the Fragment that will be handling the UI. Another example that comes to mind would be fetching location data. If the location data is going to be used throughout the app, and your FragmentActivity is hosting multiple fragments, it makes more sense to get the information in one place and simply update the fragments individually.
(2) If you're using something like AsyncTask for one-off downloads, posts, or other things unique to a specific fragment, there's nothing wrong with keeping it localized to that fragment. In fact, in that case, it would be less efficient to off load the task to your FragmentActivity than to complete the task localy.
Really there's not "right" answer. Just a question of how your app is structured and what you're trying to acomplish.
Actually the best practice for software in general is a little different, first of all you need to know that there's no "Hard Rules" to anything in software, the keyword is "All Depends(Taken from book Pragmatic Thinking and Learning)" and as such, it all depends on what you want and what you need, you should put things on a balance to know where is better for you, but going back to the best practice in general for these cases the best is to have a Business Model Class completely decoupled from either Fragment/Activity or any other android component, you are actually supposed to have a Model Class and together with a Controller Class, both of them should manipulate/populate the data and views within those elements...
Hope this helps.
Regards!
There's no hard and fast rule, but I like keep them in the scope within which they most naturally fit. If the result of a long running task is only useful within the fragment which initiated it then it lives in the fragment. If the task may affect multiple fragments then it might live in the activity.
In the past few months I have been focusing on cleaning up my code for readability purposes. As my app gets larger, it's critical that I have a handle on my variables, classes, methods, etc.
This being said, I often question my decision to create a global variable as opposed to pass a method argument and create a method variable. I find creating local method variables cleans up the remainder of my code by "hiding the overhead", however, I find there is a trade off having to trace and understand the flow of passing method arguments.
Ultimately I believe the best practice comes down to creating minimal overhead by initializing variables at as low a level as possible, essentially:
One should only use global variables where the variable is required in multiple methods.
One should use a method argument and a method variable where the variable is only required in said method and hence is local to said method.
Is that the simple logical way to approach global vs. method variables? Any advice on this line of thought would be much appreciated. As my code begins to grow into hundreds of methods I need to take more care to create my variables in the most logical way.
Thank you for your advice!
Using global variables is considered bad programming practice in most programming languages that I know. You should use params whenever possible. If at all you need something like the singleton pattern.
If you want to store some global thing you should extend Application class, it some kind of session in Android. In this class you can store everything global.
And don't use singleton, it's a bad practice in Android, use Application class.
This is not an easy question to answer in a few sentences. Use of global variables is a bad practice. It leads to tightly coupled code and makes it very difficult to modify or enhance. The need for large numbers of global variables is an indicator that you need to focus on your design.
You mention your code having hundreds of methods. How many classes do you have? If you have hundreds of methods in a single class, that one class has way too many responsibilities. Your design should focus on having classes with clear responsibilities. Each class should have only the data that it needs for handling those responsibilities. This in turn will lead to a reduction in the number of global variables. If the data is clearly the responsibility of one class then it shouldn't be global and accessible to other classes.
I was wondering if instead of having to create a new class for each activity is it possible to create mulitiple activities within one class?
So define various layout xml for various activities within one class, instead of having to create new classes for each activity.
Thanks
No, you should put each activity in seperate class. Take a look at this question. Someone is wondering just the same thing as you.
Ricky,
Yes, you may have multiple "Activities" defined inside a single class. But there are a lot of obstacles and issues with doing so. Before I answer this question, two things must be understood:
What you are asking goes against the Android guidelines for development, and those guidelines are enforced in as many ways as they can be during the compilation process, so nothing I say here is insured to work across any or all API versions of the Android SDK.
Different development environments do their own checks and compile in slightly different ways. I will be speaking from the Eclipse side of development.
Techniques listed here are for education, but introduce a lot of issues. For self education and theory, it is a wonderful practice to explore. However, the goal of this answer is to educate you as to why the guideline should be followed rather than sidestepped.
Requirements for an Activity
The first thing to understand is that Android has specific points that must be met for an Activity to be run. It must: a) be declared in the manifest; b) have an intent-filter describing how it is to be used; c) be a public class; d) be a top-level class.
Multiple Activities, Same Parent Class
This means that you may create an Activity inside of another class (an inner Activity, so to speak), but it must be declared static and public. This limits your Activity in a huge number of ways. Calls to methods or members that are instance-related (not static) to the parent class are not possible. So you lose a lot of time and code hacking around this.
Second, it affects your Android XML declaration for your Activity. This is where the real trouble comes in, because while it can be done, it is very specific and there is not any supporting documentation to make that happen. But that's okay, you wanted to know if you could make ONE class for your Activities.
Multiple Activities, Same Class
Well, Android determines which Activity to run based on its Intent. You could declare the same class multiple times, but with different Names and Intent-filters. If this is the case, then you would have to determine what to do based on the Intent and the extras included. This would be done in your onCreate() method.
Doing things in this manner would mean that you would have to code for two Activities in every place that you would normally deal with one. This would make it much harder to track down bugs to support your product. It would also make every routine operation take longer as you would have to decide which method to perform. For instance, if you overrode onDraw(), you would have to know which Activity you were drawing. Its ultimately just a big schmorgasborg (sp? does anyone know how to spell that word?) of "what do I do?!"
The Real Question
Why would you want to do this anyway?
1. If the answer is to save yourself time navigating your own project, believe me... That won't really happen. Your code will be harder to read, interpret and debug.
If the answer is that you want to save file space, I would reconsider your project's priorities.
If the answer is that you want to share functionality, consider extending Activity and then extending your new sub class. How do you think they made the ListActivity or TabActivity to begin with?
If you want to save state, you can place state in SharedPreferences or your Application object (if you have extended it).
As you can see, no matter your needs, there are many other ways to go about it in a way that doesn't cause you or anyone else a hassle.
Hope this helps,
FuzzicalLogic