I'm developing an application in which I build a treeView with some data. As the process is quite long I'd like to be able to save my built treeView (a LinearLayout) in some way to restore it when the activity is recalled.
Let's call my activity with the treeview T. I have Home->T->Resource and from Resource I go back Home. I implemented the onSaveInstance in T so there I can save in a bundle the variables I need when from Resource I go back Home and T is destroyed but the problem is that I'm not able to save all the linearLayout as a monolitic information in a bundle, the LinearLayout seems not to be parcelable.
So to summarize my cycle is:
Home-->T-->Resouce-->Home (T is destroyed and onSaveInstance is executed)-->T (I want to avoid the rebuilding of the LinearLayout).
Many thnaks
Don't do this. When you create any View, a layout or otherwise, it uses the inflating Activity's context to get and use system resources and internal app resources. When your Activity is destroyed, this context is no longer active.
If you do manage to save and load the LinearLayout back, you will get a lot of leaked windows, and other crashes, possible including NullPointerExceptions and Dead Objects.
You should always let Android recreate the layout for an Activity if the Activity is destroyed and started up again.
Why not save the resource elements of the 'treeView T' in some ordered data structure such as an ArrayList, HashMap etc... Save this data structure to a SharedPreference/Bundle etc... Whilst building the activity view, create the LinearLayout dynamically by reading the elements from the previously saved SharedPreference/Bundle.
/* Posting an example code below */
LinearLayout linLayout = new LinearLayout(this);
View childView = null; // read this childView in a sequential manner from the sharedPreference/Bundle
linLayout.addView(childView);
Related
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 ).
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).
I programmatically create a RelativeLayout with some other views inside it and add it to the parent which is defined in XML. But all the views (incl. the layout) that were created programmatically disappear after the activity is re-created. Do I need a SharedPreferences object to save the values and then re-create the layout or is there an easier way to save it?
P.S. all new created views get an id assigned
Do I need a SharedPreferences object to save the values and then re-create the layout
You say that you are creating these widgets in onResume(). Your code in onResume() needs to know what widgets need to be created. If this is purely transient information, and you are worried about things like the activity being destroyed and re-created due to a screen rotation or other configuration change, use onSaveInstanceState() on the activity or fragment to pass data about these widgets from the old to the new instance of the activity. If, on the other hand, you are worried about being able to re-create these views several months later, you need to store this information persistently: SharedPreferences, database, some other file structure, "the cloud", etc.
I recommend you look into Activity.onSaveInstanceState(Bundle):
The default implementation takes care of most of the UI per-instance state for you by calling onSaveInstanceState() on each view in the hierarchy that has an id, and by saving the id of the currently focused view (all of which is restored by the default implementation of onRestoreInstanceState()). If you override this method to save additional information not captured by each individual view, you will likely want to call through to the default implementation [ via super.onSaveInstanceState() and super.onRestoreInstanceState()], otherwise be prepared to save all of the state of each view yourself.
https://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)
as well as my answer here:
How can I assign an ID to a view programmatically?
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
Guys I have watched tutorial on YouTube about android it has 200 videos but didn't explain what is Bundle, View and Context.
1st question what is Bundle?
2nd question what is bundle inside onCreate method where that come from? what inside that bundle?
3nd question what is Context? what I found is that Activity extends Context, so is it right to say that Context is the activity itself? or the Context of that activity?
4th question what is View? what I found is that TextView extends View and other widgets like Button EditText extend TextView so it means they also extends View.
I also found that the syntax of Button, EditText and other widgets is this...
TextView(Context);
Button(Context);
EditText(Context);
so my assumption here is that "Context = Activity = Screen" and that "View = Button = TextView = EditText"
so in this example
public Example extends Activity{
onCreate(){
Button buttonObj = new Button(this):
}
}
Button buttonObj = new Button(this);
"this keyword" here is refering to the Example class which extends Activity. Is this code here basically says "put this Button which is View inside the Context which is Activity which is the Screen"?
If I am right then why Activity passed inside Button? because it makes sense if button is passed inside Activity.
5th question what happen here?
add.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
//code here
}
});
What is new View.onclickListener() ?? is this a static method that returns an object who implements onClickListener??
Can you also suggest good books in learning android?
Bundle ~ a Bundle is a collection of data. When an Activity starts (via onCreate), the Android OS (or you!) can pass off some extra data to this activity via this bundle. Do you know what a HashMap is? A bundle is a glorified hashmap in that supports multiple different types.
OnCreate Bundle ~ This bundle comes from Android. Honestly, don't worry about it too much. If you want to start one activity from another, you use an intent (do you know this yet?). As such, you can "bundle" data into the intent (using the setExtra methods). This data from the intent will be included in this onCreate bundle, and you can access it through there.
Context ~ your running application and anything associated with it. When you run your application, everything associated with your application is referenced by this context. All of you activities, views, resources, EVERYTHING is associated with the context. Think of it as the word defines: It is the context of your application. Every application has a unique context.
View ~ A view is anything that can be drawn on screen.
OnCreate():
The entire lifetime of an activity happens between the first call
to onCreate() through to a single final call to onDestroy().
An activity does all its initial setup of "global" state in
onCreate(), and releases all remaining resources in
onDestroy(). For example, if it has a thread running in the
background to download data from the network, it may create
that thread in onCreate() and then stop the thread in
onDestroy().
OnCreate method is called when the activity is first
created. This is where you
should do all of your normal
static set up — create views,
bind data to lists, and so on.
This method is passed a Bundle
object containing the activity's
previous state, if that state was
captured.
Views:
The visual content of the window is provided by a hierarchy of views — objects derived from the base View class.
Each view controls a particular rectangular space within the window. Parent views contain and organize the layout of their children. Leaf views (those at the bottom of the hierarchy) draw in the rectangles they control and respond to user actions directed at that space. Thus, views are where the activity's interaction with the user takes place.
For example, a view might display a small image and initiate an action when the user taps that image. Android has a number of ready-made views(Widgets) that you can use — including buttons, text fields, scroll bars, menu items,check boxes, and more.
I would suggest that you look at some text based tutorials rather than video as it will be easier to look at things and reread when you are confused.
I'll get started to help you with figuring out what these terms means.
Bundle - not super important for you to understand. When an activity is called, you can add things to your bundle to be sent to the next activity so that the new activity has the information you want.
Context - each activity has its own context and its important to have a basic understanding of it. Your first applications will have one activity (or class) from which everything is done. In this case you only have to worry about the "this" context which means the current active activity. But if you use an application with multiple activities, some may be active and others not. The context tells your app which of the activities is requesting an action, such as showing text or an image on the screen.
Views are your basic UI elements. They can be simple like TextViews (just shows text), Buttons, or more complex like a layout which organizes the other views.
For your example :
public Example extends Activity{
onCreate(){
Button buttonObj = new Button(this):
}
}
Example is the name of your class which uses the Activity resources.
When the activity "Example" is started it calls the onCreate method first.
It then creates a button object that you can "attach" to a physical button found in your layout file.
The setOnClickListener method is used to ready your activity for a button click. The code that goes into the onClick section is what will happen if the user clicks the button.
If you want to get into android programming, you really should first read the FAQ on this site. You should only be posting answerable questions not asking for opinions such as what's a good book. Hundreds of people have already asked that question and if you can't do a simple google search, you might want to wait on learning to program.
But I"m nice so here are some online tutorials that will get you started and explain some of the things you are confused about:
http://developer.android.com/guide/index.html
http://www.codeproject.com/Articles/102065/Android-A-beginner-s-guide