I have a CustomListActivity which I wish to expose two facets of the same data.
For example: I have a list of cars, and would like to list the set of colors, and the set of models. These would be filtered on mimetype from my ContentProvider:
org.acme.cars.cursor.dir/colors
org.acme.cars.cursor.dir/models
My CustomListActivity is quite involved, but general enough to be re-used, but:
the user should be able to swap between the two lists from a menu/button bar
the list is MAIN LAUNCHER intent.
the user's choice of facet (model or color) should be remembered
we should be able to call these activities via mimetype.
So, my question is:
Can I declare two activities in the AndroidManifest.xml, each one with the same class, parameterizing it, or do I need to use some switch from within the class?
Why not keep it a single activity, keep the layouts in separate XML files, and use setContentView to switch between them?
Related
Is it better to pass a datatype like list through an intent or it's better to make it global and use everywhere?
Right now, I am not sure whether other activities in my application would be needing that list or not except the one to which i am passing the list through intent.
and making it global would break encapsulation so i am not sure what's the better way.
It completely depends on your needs.
If you just want to transfer values from one activity to another, you should go with intent. Even if there are very few number of activities which would need that value, it would be better to use Intents.
But in case you want to use the same value in all or most of your activities, you should go with global declaration.
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.
I've got this question regarding Android activities and AndroidManifest.xml. The question arised when I was working with Java servlets, and wanted to create a "module-based" or something similar to plugin based server. This is working fine, and I can dynamically load the servlets I want, using a code approach similar to this: Dynamically add a servlet to the servletConfig. The servlets are dynamically found and mapped during the server startup.
The question here is not how to find the proper activities, or how to create a new instance of them, or how to start them, that part I have figured out. I can iterate over my packages and find the appropriate Activity-classes, create new instances of them and add them to a list.
I've been using a interface which all the Activities must implement in order to be a valid activity. That way, I can create new parts, extentions or new features for my application, and everything just works. In my application I have a list of button that users can click on, and the button list is generated by adding them to my view using a ListView.
private void displayLoadedContent() {
View v = inflateLayout(R.layout.buttonlayout);
ListView view = (ListView) v.findViewById(R.id.list);
view.setAdapter(new ListButtonAdapter(this, content));
}
where content is declared as
List<MyActivityInterface> content;
and ListButtonAdapter extends BaseAdapter.
So no problem there. The problem is that I have to declare each and every single one of my activites in AndroidManifest.xml. That file is like a big list of possible acitivies to display, and kind of messy, so I'm not going to display the code here.
I realize that I'll have to add one activity to the manifest, but I was hoping that the one activity should be enough. My approach can in many ways be looked as a Front Controller pattern, where each of the activities is responsible for loading and displaying the acitivity they need.
I'm simply asking if it's even possible to dynamically registrer activities in the manifest (or allow them to run in another way), and if no, is there any other valid solution?
Android requires that each activity to be registered in your AndroidManifest.xml file ahead of time. When deployed, your app will live on a device as an .apk file, which can't be modified (aside from being updated/replaced with a new APK).
If I understand the question correctly, you simply don't want to have to list a large number of activities in your manifest file? Fragments don't need to be registered in the manifest file, so if your goal is to dynamically swap out UI components, that would be the answer. Fragments are available back to 1.6 via the Support library.
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 have a similar issue with this one:
Android: Multiple activity instances launched by same intent. Bring one uniquely to foreground?
I need to create a stack of activities, all created by using the same class: it is a class defining a news list, only there needs to be multiple children activities that are also news lists, but from different categories. (I do need to have these activities in a stack)
The trouble is I need to change data on each of these activities after they are shown, but I can't find a way to access each one of these activities separately, since they are all using the same class, so if I used static methods, I would change the data on all these activities at the same time. Ideally, there could be a way to use references of each activity, so that I can access methods on each one separately, but I don't think there is a way of doing this.
I might as well pass parameter IDs when starting each activity, and instantiate objects at the same time, for each activity, and using these IDs later access the respective objects' methods...
Edit to clarify: Let me use an example to what I am trying to achieve. I have an A class and I am using this same class to instantiate multiple activities, in a stack. After the creation of these activities, I need to alter data, say, on one of these activities statically, so by calling A.alterData(); , but not when the activities are created, so there is no way of doing this by starting the activities with different data.. Since there are multiple instances of this class, if I do so, this will result on altering the data on all these activities, that are using the A class. Would I be able to somehow use objects and methods to these objects to alter data on different activities that are using the same class?
any other ideas?
You could use an ActivityGroup. It basically holds a list of activities and you need to control the navigation around them. It sounds like it suits your situation. There are many examples of them that can be found through google.
How I would approach changing the data on the other screens is by using shared preferences. You can store whatever data you need in there, and then (through your activity group) when you change screen, the data is refreshed. This is faster and a little more efficient than restarting the intent every time.
Another way is to change the data in the background without the user noticing. This can be done because an Activity group loads all of the Activity it holds and they are always there in the background, running, unless the developer states otherwise.
You could grab a a hold of the appropriate instance of the class you want to change the data on and then just change it.
Does any of this make sense?
I can elaborate more if needed.
I would supply the parameters to each activity, such as:
intent.putExtra("category", categoryId);
That way you aren't managing too much global state.
About changing the data - if you are talking about refreshing the data from its original source, then you should probably be doing this in the onResume() method of the Activity. Check out the Activity Lifecycle.
This has a few benefits:
you will have access to all of the context of that Activity
you won't have to do something nasty like access another Activity's data
you won't waste time refreshing data the user isn't looking at
Even if you have to make updates to the data, there are ways to make sure each Activity "minds its own business".