How can I call function (with parameters) in parent activity from child activity in Android. I iOS is simple with delegate and protocols, but in Android I found that can be a problem if the screen is rotated.
I also do not want to use startActivityForResult because I do not want to close the child Activity.
ADDED:
I am creating a library so other developers can attach it to their project. In developers activity they put button that shows my(by my I mean from library) Activity and when something is done in my activity I instantly need to inform the main project(activity) that something happened (via function or something), but I do not want to close my activity yet. I also should not change their code a lot and it should be easy to include to their code.
The point is that once you started a child activity, Android might decide to close your parent activity at any time, if system requires more memory. This means you cannot rely on the fact your parent activity still runs. That is why you cannot use static variable approach either, because parent activity might not be there already.
If you want your app to run reliable in any situation you have to use startActivityForResult and close child activity.
If this is not acceptable for you because of some reasons, you might share more details and we will try to find an appropriate solution for you in terms of Android concepts.
ADDED: I am creating a library...
As already mentioned, you cannot control whether your parent activity gets closed or not as long you started a new child activity. Android can kill your parent activity at any time and you need to be prepared to handle this situation properly.
To solve your problem you need a place, which is shared between parent and child activities. A sequence will be like this. Parent activity starts a child activity and goes into background. User changes something in child activity and it stores changes (as data) into the shared place. At this step it doesn't matter whether parent activity still running or now. Once parent activity is visible again, if must read data stored by child activity, and update itself accordingly. You can use onStart() method for this.
Now about that shared place. I would discourage you from using a static variables. Instead you could use Application object (it's a singleton) or shared preferences (they are also shared).
Related
Since the child activity is created by calling the startActivity(intent) from the Parent Activity, it is guaranteed that the parent object exists while the child activity is running.
From that point of view, can I just manipulate the Parent's public variables at the child's class instead of calling startActivityForResult() after I come back?
Why do we need to use the method?
it is guaranteed that the parent object exists while the child activity is running.
No, it isn't. For starters, startActivityForResult() can be used across process boundaries, where the activity you are starting is in another app. The activity that is started cannot access the activity that started it, as they are in separate processes. Beyond that, it is possible that the process where the original activity resides will be terminated while it is in the background, as the user is in the second activity — this happens a fair bit when the second activity is a camera app, launched in response to something like an ACTION_IMAGE_CAPTURE Intent.
can I just manipulate the Parent's public variables
One activity has no access to another activity instance. The only way that would be possible is via static references to activities, which are tricky to get right without introducing memory leaks. And, again, that would only work where both activities are in the same process.
Why do we need to use the method?
You don't. There are any number of ways of writing UIs on Android. Few require the use of startActivityForResult(). For example, if these two bits of UI are that closely coupled, perhaps they should be in a single activity, where the bits of UI are separate fragments.
I am developing a small A/B Testing library for Android. Library will only be initialised in application class. I need to change TextView values.
I will store all the data fetched from the in a file. But I am not able to track when ever a TextView gets into view and moves it.
For example TextView A is in X Activity, TextView B is in Y Activity and TextView C is in Z Activity. Since the variable I have is Context, how should I change TextView A, B, C values.
I need to figure out which Activity is Visible. From the Activity I will be able to get root view. And I will iterate over child views and change value. But How should i listen to Activity Change.
Is there any other approach to this ?
I know this is possible as many A/B testing library are doing this.
Here you go, check out my answer over Here
As you've mentioned, hooking into the activity lifecycle callbacks via AppContext is the best way to start. From there, you'll have all of the information you could possibly need. Every time the activity switches, you'll have the Activity object, and from there you can get the root view and apply changes as necessary.
I would advise against an iteration over the views though! If you have the rootview, you can just do a findViewId(textview C id) on that root view and you'll grab your view!
Since you are building a library, you can expose a function which can be called after onCreate of each activity, which will give you reference of the activity. Once you have the activity, you can get it's root view and do whatever magic you want to do.
That's the only other approach if you don't want to register LifeCycle callbacks for activity. The application needs to enter your library at least at some point of time. Either you can make the application do manually ( above approach ) or you can override all life cycle events of all activities ( registering lifecycle call back ).
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.
I need to hide the tabs of a TabHost from a child activity. I tried getParent() and it didnt work
Also tried :
TabHost th = (TabHost) ((TabsActivity)getBaseContext()).findViewById(android.R.id.tabhost);
th.setVisibility(View.INVISIBLE);
But it throws a nullpointer
Never directly access Views owned by other Activities from the current Activity, because they might have been recycled in the meantime (because the other Activity might have got destroyed in the meantime).
You need to communicate with the other Activity in a standard way. For example, your child Activity can return a result to the parent Activity, which it can then interpret (you can put the value to the Intent). Another solution is using a static variable, but this is not too nice and has risks if you're not careful enough.
For more information about communication between Activities, see this and this.
You won't be able to directly manipulate the view hierarchy of an Activity not currently in the foreground because it likely would have been paused and stopped, in which case its UI has already been destroyed and won't be rebuilt until it comes back into the foreground. You should consider what things take place in the Activity lifecycle to help you solve this. A quick and dirty solution could be that your Activity hosting the tabs has a public static variable that can be set by other Activities; such that when it resumes running in the foreground it can check that variable and make Views visible or not as needed
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).