I have an activity which has a static method for updating a textfield. This way I can update this view from another activity.
But now I'm trying to get a Context variable in this static method which is not possible. I've tried declaring a Context variable and initialising it in onCreate ( context = getApplicationContext();)
But still I can't access context in this static method. How is this normally done?
edit: a little bit more information about my situation. I'm starting a countdowntimer in an activity(a) which updates another activity's(b) ``textfield every second. And it does this by accessing b's setTextField in a static way..
How is this normally done?
Accessing a TextView via a static method is not the best way to update the field from another activity. If you want to pass a value to the activity when it starts, you can send data via the intent (i.e. intent.getExtras). If you want to pass data back from a sub-activity, you can use startActivityForResult.
The way you are going is very strange. Why are you trying to change one activity content from another? May be you need to use startActivityForResult to strat a new activity and then return result from it and change views depending on it?
You might want to check some documentation on OO and using static functions. It is not considered a very good approach.
But as we are not talking about a better complete sollution: you can add a parameter with a context to the function, and just give it when you call the function :)
I would suggest the LocalBinder pattern to update the other Activity:
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html
Can you do something like this?
something like this <viewobj>.getContext()
Ref: How can I start an Activity from a non-Activity class?
Whenever you're busy with Activity A, there's no point in updating something on Activity B as it is simply not shown to the user at that point in time.
Seems to me you need to have some kind of global variable here that can be picked up in the onResume of Activity B.
Checkout this question : How to declare global variables in Android?
It shows you how to use the Application class to maintain global application state, accessable from all activities when needed.
Related
Trying to call a function from an activity, but I need the specific instance of that activity to do so.
Is there a way to call that specific activity from the application?
If not, is there a way to start an activity from the application so that I always have access to the instance I start running? I tried this, and edited the manifest, but the app never started...
As concerned with the limited details in this question, I think your requirement is to call a function in an activity that needs that activity itself as the parameter. I think you can do it like this.
Activity actiity=this;
yourMethode(activity)
{
//body of your methode
}
Whenever you use the variable "activity", you can get an instance to the current activity.
I think you are talking about casting the context to get the type of activity it represents. You can do it like this. But be careful if the context is not of that type you will most likely cause a crash.
((MainActivity) mContext).myMethod();
This is not really recommended as it will cause some tight coupling between the class and the activity.
Over the development of an Android app I've come to a collection of utility-type methods that I have put into a static class. All these methods are used across multiple Activities and most of them do not require any information from the calling Activity.
However, I now have some methods that require the Context of the Activity and one that requires the Activity itself. Let me exemplify some of them:
getDeviceNaturalOrientation() - Uses an Activity's
getWindow().getWindowManager().getDefaultDisplay() to access the
displays rotation, width, and height to determine the device's
natural orientation.
getDeviceOrientation() - Similar to the above but to get the current
orientation
createFile() - Uses the Context to to access some resources (strings) and to
create and show some Toasts
Now, my big questions regarding this Utils class are:
So far, each function takes a Context parameter which I pass from whatever Activity I'm on, but would it be OK to create a static Context or Activity variable in the Utils class and set it at the beginning of each Activity (like in onCreate)? This variable would be used in whatever functions require a Context or Activity instance.
Assuming the above is not recommended, is it OK to pass an Activity parameter to a method or is there a reason to only pass an Activity as Context? The methods I use for the device orientation functions above are specific to Activity objects, not Context, so either I pass as Activity or pass as Context and cast into Activity (the latter sounding like a terrible idea).
Also, I am very open to the idea that this Util class may not be the way to go for these methods that require Context/Activity, so I would welcome alternatives that would still prevent having copies of these methods in each activity class that uses them.
1)A static link to a context is likely to cause a memory leak. It means that a reference to the Activity will be kept around in the static variable even after its destroyed, so all of the memory of the activity and all its views will remain valid and not be cleaned by gc. You can do this, but you have to be careful to null out the variable when done. Its better just to avoid it.
2)Its a little bit awkward to pass the activity as an Activity, but no technical reason not to. At that point we're arguing over code cleanliness/maintainability. And there are times where the non-clean solution is just easier. Of course in the cases above I'd rather pass the orientation/display/Resources objects to the function than pass the entire context or make special accessors.
I think following design should be fine when you call from Activity
MyUtility utility=new MyUtility();
utility.getDeviceNaturalOrientation(this);
utility.getFile(this);
And you can define these function like
public int getDeviceNaturalOrientation(Activity activity){
//code
return some_oreientation
}
and like this
public File getFile(Context context){
//code
//return file handler
}
Activity is the subclass of Context so you can even change the design to following
MyUtility utility=new MyUtility(this); //this refer to Activity
utility.getDeviceNaturalOrientation();
utility.getFile();
As long as you pass activity you are fine but if you do following from your activity you will get error from first method call
MyUtility utility=new MyUtility(getApplicationContext());
utility.getDeviceNaturalOrientation(); //will throw exception
utility.getFile();
And, yes first idea is not a recommended way.
I would suggest you to send a WeakReference of your Activity or getApplicationContext() (for those works which can work using it) and don't use static method because it cause memory leaks. Read Developer blog also
can I use activiy one time(register activity) and switch the main launcher after using to different activity?
another question if I may,
If I create parameter x in one of the activities in my application, can I use this parameter in other activities?...If yes, how I can do that?
thanks :)
You cannot dynamically change the launcher activity once it has to be only 1 activity that is defined in the manifest file.
I would recommend having something like a landing or splash activity which checks a shared preference variable, to decide which activity to launch, for example either a login activity or another activity.
You should not access a variable in an activty from another activity, you should store these in data holding classes. however if you want to do it, for a good reason, simply make it static.
You cannot adjust the manifest after running your application. What you can do is have your default launcher activity write to SharedPreferences once it has been run once. Inside of that activity check to see if that preference has been set and if it has just finish that activity and launch your new activity, the user will not see anything if you do this in the onCreate of the launcher activity.
As for passing params between activities you should use intent extras. For example to pass a string use putExtra(String key, String value), and to get that parameter inside of the new activity use getStringExtra("Key").
For global variables accessable from different activities you can also extend Application class and then access it via getApplicationContext().
1. One time activity launch
You can't change the main launcher. It's a static information. What you could do is following:
// in the beginning of onCreate
// first launch could be loaded from shared preferences
// see 2. for more
if (!firstLaunch) {
// start another activity
finish();
return;
}
2. Use data in another activity
One way is to persist the data and load it somewhere else. You will find all information you need in the Data Storage article.
If your data is primitive you could try to pass it by intent to another activity. See Using integer from one class in another Android.
If it is complex you could try to implement an own Application class and use helper methods to access global data. See Android: Accessing resources without an Activity or Context reference.
Be careful with that, please read the Avoiding Memory Leaks article then.
My launch activity starts up another activity whose launch is set to single instance. In this 2nd activity, I have a public method. I then start up a 3rd activity and that activity needs to access the public method in the 2nd activity. I don't want to use startActivity and pass it extras because I assume the onCreate will get called (or am I wrong?) and I need to avoid the 2nd activity from reinitializing itself.
When an activity is started using startActivity, is it possible to gain access to the underlying class instance itself and simply call the method?
I actually came up with a simple solution. As a matter of fact you can access the underlying class of an activity. First, you create a class that is used to hold a public static reference to activity 2. When activity 2 is created, in its onCreate method you store "this" in the static reference. Activity 2 implements an interface with the methods that you want available to any other activity or object. The static reference you hold would be of a data type of this interface. When another activity wants to call a method in this activity, it simply accesses the public static reference and calls the method. This is no hack but is intrinsic to how Java operates and is totally legitimate.
It is not a good idea.
As I can understand method from second activity is actually not connected to particular activity while you want to call it from another one. So carry the method out to other (non-activity) class (maybe static method) and use it from both activities.
It's not directly possible to gain access to activity object started using startActivity (without using some hacks). And frankly you shouldn't even trying to accomplish this.
One Activity component can cycle through several Activity java object while its alive. For example, when user rotates the screen, old object is discarded and new activity object is created. But this is still one Activity component.
From my experience, when you need to do things you described, there is something wrong with your architecture. You either should move part of activity's responsibilities to Service or to ContentProvider, or use Intents, etc. Its hard to recommend anything more specific without knowing more details.
No there is no way to pass a reference via startActivity() however you can use some sort of shared memory to keep reference to your Activity. This is probably a bad design. However passing an extra with your Intent will not cause onCreate, that is completely related to the lifecycle.
This is a pretty simple question, but I have been unable to find anyway to accomplish what I am trying to do...
I want to launch a new Activity to display some complex information. Because of the complexity, it is undesirable to serialize the information into the intent's parameters. Is it possible for the the new Activity to get a reference to the launching activity, so it can call its methods?
If you use a custom application class, you can store information that will be kept between the activities.
See a tutorial here for instance.
The lifetime of an Activity cannot be depended upon. In this case, one way of sharing data is to have a singleton which holds the data to be shared between the two activities.
You can add a public static field to the first activity containing this (the first activity).
But beware that the first activity could be destroyed by Android while you are using the second activity, so you will have to implement a fallback method if the first activity is destroyed.
And don’t forget to unset the public static variable in the onDestroy() callback of the first activity or you will leak memory.
Is it possible for the the new Activity to get a reference to the launching activity, so it can call its methods?
Please do not do that. Android can and will destroy activities to free up memory.
Complex information like you describe should not be owned by an activity. It should be held in a central data model, like you would in any other application. Whether that central data model is mediated by a Service or a singleton or a custom Application object depends a bit on the type of data, caching models, risks of memory leaks, and so on.
You can make your complex objects public and static in ActivityA, and access them in ActivityB like this:
MyCustomObjectType complexFromA = ActivityA.complexObject;
this will work, however while in ActivityB, you can't always be sure that static objects from ActivityA will exist(they may be null) since Android may terminate your application.
so then maybe add some null checking:
if(null == ActivityA.complexObject) {
//go back to ActivityA, or do something else since the object isn't there
}
else {
//business as usual, access the object
MyCustomObjectType complexFromA = ActivityA.complexObject;
}
You could also use a Singleton object which extends Application. You would have the same problem when Android terminates your application. always need to check if the object actually exists. Using the Singleton extending Application approach seems to be the more organized way - but adds more complexity to implementation. just depends what you need to do and whatever works for your implementation.
You should create a separate class that both the activities can use.
public class HelperClass{
public void sharedFunction(){
//implement function here
}
}
I would recommend staying away from static variable in android. It can cause some unexpected behavior.
Use getParent() from new activity and call parent's method
Android Activity call another Activity method