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.
Related
I'm writing my first android app, and it's going very well so far, but my code is getting obtuse and I'd like to reorganize it in a way that allows me to reuse portions, and add things more easily.
Based on my previous experience writing simple command line programs that call methods, this is how I THINK I should organize my code:
(some code in MainActivity)
Call a void method of the object DoStuff:
Launch Activity1 and write some values to SharedPreferences file, THEN
Launch Activity2 and write some values to SharedPreferences file, THEN
continue running code from MainActivity
Right now Activity1 and Activity2 both launch at the same time. Is there a different way I should be writing/organizing my code? I guess I'm trying to do thing with Activities that I'm used to doing with methods. But I'm aware that my thinking might be wrong on this. I hope this makes sense.
Thank you for your help!
Your understanding of Activities is wrong. Activities do have methods that you can very well use.
An Activity is basically one screen that you see in your app. It can be started, stopped, resumed, etc. You can have different screens shown in one Activity (e. g. with Fragments).
If for example you have a list of notes in one Activity, you could have the detail of one note shown in another DetailActivity.
Only in rare cases, for example if you want to check on startup what Activity to show you could have another activity that does not have a layout but only does some checks and launches another one.
In each of your activities you can have methods to execute what you want on user interaction. Of course this can also go into other classes.
I would recommend you to start with a basic Android tutorial to gain a better understanding of the concepts.
I am having an architectural problem with an Android project. I have the main activity(A) where a lot of stuff is initialized then I have 1 Activity(B) that handles some broadcasts from the system, this activity needs to access the stuff initialized by the main activity. If the app is killed and the activity (B) is called the onCreate of the Activity (A) is not called so the stuff is not initialized, how can I handle this situation properly?
That's a sign of not properly encapsulating the logic.
I don't know what your app is about, so that makes it difficult to generalize, but probably your Activity A has a lot of objects and variables related to you model, what you should do is isolate all this logic of your model in a single component, that you can initialize with a single call (or a few lines) either from activity A or B.
This logic can include opening files or sharedPreference, initializing objects, downloading data... Ideally all the logic is isolated from the user interface. The User Interface, on the other hand should be only responsible to present the data in a human readable (and hopefully enjoyable) way.
When first time your activity B is called, pass all initialization values to it from Activity A and save the in Activity B.
If app is killed and activity B is called, it have all the initialized values.
You should develop App using MVC arthitucture
Check this MVC Pattern in Android Development
This will help you batter.
The Android Developer Guide states that activities are launched via Intents:
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
For Fragments, the usual way to display it on the screen is as follows:
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
Why is it that in one case I have to specify a class, and in the other an object? I.e., I would like to use something like
Activity nextActivity = new SignInActivity();
Intent intent = new Intent(this, nextActivity);
startActivity(intent);
Because Activity lifecycle is managed by Android whereas Fragment lifecycle is tied to the Activity in which it is contained.
As mentioned, Activity lifecycle is managed by Android. This is required, among other things, for Android to manage the system resources and also to take care of the back stack.
Fragment, on the other hand, was introduced to modularize and better organize the UI for devices with different sizes. According the the documentation:
Starting with HONEYCOMB, Activity implementations can make use of the
Fragment class to better modularize their code, build more
sophisticated user interfaces for larger screens, and help scale their
application between small and large screens.
To answer the latter part of your question, you can indeed pass the results of an activity to a second activity. But you should never create an instance of an Activity class for that. The right way is to use the startActivityForResult() and send the resulting value to the destination activity through the Intent.
While adding fragment, you are already specifying where exactly to insert that fragment into. So, the ideal way is to,
Create your fragment.
Insert into a layout of your current activity.
Use transactions to remove/manage your fragments, added to the current activity.
In no way, you could launch or use just a fragment, without attaching it to an existing activity.
Android handles Activity life cycle by itself. Just look at the methods of Activity class, they're just like a fill in the blanks. Android calls the shots here. Through these methods it just ask if you want to do something when this activity is created, resumed, paused etc.
The reasons for Android handling activity life cycle internally, are many:
Properly setting up an Activity involves lots of boiler plate code, better let system do it for you. The whole Context and window management is set up for you behind the scenes. Imagine the amount of extra work, if you had to do it for every Activity you created.
Activities are shared, home screen and other applications might want to launch/use them. How would be this possible if they have to call new MyActivity() of some obscure package ? . This is why Activities and other externally invokable components must be declared in application manifest.
Activities from many applications can be parts of an android task ( a piece of work from user's perspective). And are automatically placed/removed/re-arranged on a back-stack. Again, its better Android manage their creation and destruction rather than developers messing with this whole setup.
All user cares is that an Activity must show up when asked for, and just get out of the way if user navigates somewhere else. Android enforces this. Making an Activity appear on its own, or refuse to go away, just because its allowed to be programmed that way, is unacceptable.
Now Fragments , on the other hand are internal. They live inside an Activity and are not accessed from or shared with outside applications or tasks in any way. Fragments are even not a part of application manifest and hence are not exposed outside. Android need not worry about each fragment separately, because fragment life-cycle is bound to that of its parent Activity. Android doesn't care what you do with fragments internally, it can just end the activity and everything inside it is destroyed as well.
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".