I am developing an Android application and can't quite figure out the best way of implementing a 2-level image cache that can be shared among multiple activities w/in a single application.
Example:
Application has 3 activities (A, B, and C) and for the sake of argument lets say that A calls B and B calls C and C calls A. Each activity displays an image downloaded from the web and I'm using asynctask to download and display images w/in each activity - easy enough. Now I'd like to add an image cache to avoid multiple downloads of the same image.
Right now each activity starts a new instance of a simple asynctask that downloads the image and updates the view appropriately. Obviously its easy enough to update the basic asynctask to check the image cache before proceeding to download and to update the cache once the download is complete but I'm stuck on how/where to create and initialize the cache. Any thoughts would be appreciated.
You can add this to your app's manifest:
application android:name
="MyApplication" (...)
You can then create a class that has the name "MyApplication". You can then use that class across your activities. Check, before making the async call, if you already have a proper image to use. If you have, you use the one "cached", if not, you can get a new one. You can try something like this (in this case to get some random strings):
ArrayList myStrings =
((MyApplication)
this.getApplication()).getRandomStrings();
Hope this helped you. :)
Edit: Don't forget to the create your "MyApplication" like this:
public class MyApplication extends
Application
Related
I am making an Android app using the Parse SDK. What I am struggling with is the flow of creating a post. Currently, in my main activity, a user selects the type of post (photo, video, etc.) takes a photo/video and goes to the next activity called NewActivity. In this activity, a user can review the photo/video and edit the privacy or place of the post. to change the privacy or place launches a new activity for each.
The main problem I'm having is retaining and passing this Post object between the activities.
My first (bad) solution was just to pass the data with the intent in a Bundle, but this soon got very messy as I really needed to pass a Post object between the activities. I switched from that solution to using a Singleton class called, DataHolder.
In each activity, I call DataHolder.getInstance() and when the create post button is clicked, I create a new Post object by executing: DataHolder.getInstance().setPost(new Post()). In the following activities, as the user enters more information about a post, I set the Post's properties.
This was all working well until I ran into this issue. When I would return to my app (presumably it had been killed) I would get a NullPointerException because the Post object was null. I was looking through the Android docs on passing data between activites/services and needed a little help.
Should I be using the Singleton class pattern here? What would be the most efficient and easiest way to pass this Post object between the activities? Should I use an application singleton? I would use Parcelable or Serializable, but the Postobject is a ParseObject so this is not an option. Should I avoid passing the data altogether by using Fragments for the privacy and place activities (though they have different screens and different action bars)? Should I use startActivityForResult for the privacy and place activities?
You should consider that the app could be killed at any moment for any reason and be prepared for this. You could use something like a session object to communicate between activities. You can save it / load it as often as needed so you will not run the risk of loosing data. If you cannot serialize the actual object (eg the ParseObject) you could serialize the parts needed in order to reconstruct it (ie save the image in a temp folder and load it on demand).
In my Android Application, I have two activities.
One Activity lets the user take a picture. This picture is saved, and then uploaded to the server. The server returns some info and displays it in a list.
The other Activity is a gallery. The user can select a picture, upload it and get the same info in a list (the same as the first activity)
The way I've implemented is this:
upload and Info task is a seperate AsyncTask called WebServiceTask. Both Activities execute this task.
I created a WebServiceTaskInvoker interface so that each activity could specify what happens on preExecute, postExecute, progressUpdate.
The problem is that the two activities pretty much do the exact same thing on preExecute, postExecute and progressUpdate so there's code repetition between the two activities.
OnPreExecute: Both Activities check internet connectivity
OnProgressUpdate: Both Activities change a TextView's text
OnPostExecute: Both Activities create a dynamic ListView and populate
it with results.
How can I fix this?
I know one way would be to combine the two activities into one but form past experience, I've known this to be troublesome and messy.
I could put the UI code in the WebServiceTask but that would lead to tight cohesion.
Implement a base class for the two activities that executes common code. Implement the activities as subclasses of your base class to execute different code.
An alternate to Catherine's suggestion is to create an activity mode enumeration.
Pass this mode as an extra when launching your activity.
If the mode is MODE_GALLERY then load the gallery.xml layout and populate it, if not then load the other layout.
Just make sure that you use the same id's for the common views, an easy way to do this is to use the include tag in your layout files.
The advantage of this is that you only have one activity file instead of three which would be required for the subclassing method.
You may also be able use fragments, but I don't have any experience with these so I can't advise ou further.
One last note, I would avoid putting UI code into a task.
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
I have an app with multiple activities and multiple layouts. However, one piece of layout is included on several activities. I also have a thread which updates this layout. However, when i switch activity it doesn't work. Since the layout is included the elements have the same ID's, shouldn't it just work? Or do I really need to fetch an object for each element in the layout and feed it into my thread in order to make it update the elements in a new activity?
You should run the update code for each Activity/View, although the XML included is the same, each is a different instance.
My suggestion is on Restart verify is there is any modification to do in each activity, a simple way is to each Activity extend a BaseActivity that has this code.
I include a layout for adverts in my app, but on each activity that uses it, the adverts need to be reloaded.
If I call an activity from one that is using the same included layout when I go back to the previous activity it's still there.
I guess this is what you are seeing....
So you can also save that data inside sharedPreferences (if it is little data and primitive objets or parceable objects).
Also you can extend the Application class and store the data there and update every activity inside the onResume() method. that i believe is the best way to handle this. and this is quite simple to do.
Ask google about extending the application class and he will provide tons of results on how to do it. its an easy way to pass data between activities and/or keep a reference to a single object which you will use throughout the app. Just be carefull to clear it when you wont need it anymore because it will stay in existance untill the application is finished() (which comes with the application extension living thru the whole application lifetime).
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.