What is the difference between Context and Acitivity? [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between Activity Context and Application Context
When to use Context and Activity.
I have read code that uses both Context and Activity as parameters in Constructor like below,please clear me on this
public AmazedView(Context context, Activity activity) {
super(context);
mActivity = activity;
// init paint and make is look "nice" with anti-aliasing.
mPaint = new Paint();
mPaint.setTextSize(14);
mPaint.setTypeface(mFont);
mPaint.setAntiAlias(true);
// setup accelerometer sensor manager.
mSensorManager = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
// register our accelerometer so we can receive values.
// SENSOR_DELAY_GAME is the recommended rate for games
mSensorManager.registerListener(mSensorAccelerometer, SensorManager.SENSOR_ACCELEROMETER,
SensorManager.SENSOR_DELAY_GAME);
// setup our maze and marble.
mMaze = new Maze(mActivity);
mMarble = new Marble(this);
// load array from /res/values/strings.xml
mStrings = getResources().getStringArray(R.array.gameStrings);
// set the starting state of the game.
switchGameState(GAME_INIT);
}

Context: is a handle to the system. Context contains environment data such as local files, database, ... Context also include many system services. For example, Context will provide access to Location Service,... Also, with context, you can use resources, access to databases and preferences, local data ...
Activity: extends from Context. And not only Activity, many others extends Context, and each has its own purpose such as: FragmentActivity, Service, WallpaperService. More detail in Activity, "normal" android app has activity. It's like a handle to the environment your application is currently running in. Activity can create UI (User Interface)
In your above code, depends on other constructor, you should put context or activity object into. And as you see, if activity takes from the same context, you can use one parameter in the constructor
public AmazedView(Context context) {
Activity activity = (Activity) context;
}
But you can see, it's not clear, and "hide" real object behind. Because Activity is the subclass of context, so in an informal way, Activity has some "additional things" that context doesn't have. If you put it as a context object, no one knows that fact and will make the code seems obscure. Moreover, context might become from Service for example, and you will don't sure when typecasting to Activity. So, make two parameters is suitable here.
More importantly, you should carefully to use Activity as the context object because it might cause a memory leak.

Application context refers to the application environment and the process within which
all its components are running. It allows applications to share the data and resources
between various building blocks.An application context gets created whenever the first component of this application is started up regardless of whether that component is an activity, service, or something else.Application context lives as long as your application is alive. As such, it is independent of the activities life cycle. You can easily obtain a reference to the context by
calling
Context.getApplicationContext() or Activity.getApplication()
keep in mind that activities and services are already subclasses of context, and as such they inherit
all its methods.
An activity is usually a single screen that the user sees on the device at one time. An
application typically has multiple activities, and the user flips back and forth among
them. As such, activities are the most visible part of your application.
you can also take a look at this : What is 'Context' on Android?

On the developer page of android:
http://developer.android.com/reference/android/content/Context.html
it states:
"[A context is an] Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc. "
An Activity is an indirect subclass of Context, as mentioned on the page.

Related

Passing references to Activity Intent

For quite some time I've had troubles passing variables from one Activity to another, and I've usually had to resolve to some pretty ugly Static-class-hacks to make it work.
Generally something along the lines of a static method that I call with the type of the Activity, along with the variables the Activity requires. These gets stored in a static variable, and retrieved in the constructor of said activity.
Like I said, pretty ugly. And there's no such thing as "myActivity.StartActivity(new Activity);". All of the overloads for StartActivity takes either an Intent, or a typeof(MyOtherActivity).
So my question is, have I completely misunderstood the concept of Activities, or am I simply missing a completely obvious way to pass arguments to them?
#Edit: The reason I want to pass an actual reference to an object, instead of simply a copy of the object, is because I'm trying to pass a View Model from an overlying Activity, down to the new Activity. And of course any changes made to this view model, should be reflected on the parent activity, which will only be possible if the the two activy's viewmodels points to the same instance.
I'm writing the app using Xamarin.Android, but the code is nearly identical between C# and Java, so answers in either those languages is fine.
The problem is that Android can kill the process hosting your app at any time (if it is in the background). When the user then returns to your app, Android will create a new process to host your app and will recreate the Activity at the top of the stack. In order to do this, Android keeps a "serialized" version of the Intent so that it can recreate the Intent to pass it to the Activity. This is why all "extras" in an Intent need to be Parcelable or Serializable.
This is also why you cannot pass a reference to an object. When Android recreates the process, none of these objects will exist anymore.
Another point to consider is that different activities may run in different processes. Even activities from the same application may be in different processes (if the manifest specifies this). Since object references don't work across process boundaries, this is another reason why you cannot pass a reference to an object in an Intent.
You can also use The Application class to store objects globally and retrieve them:
using Android.Runtime;
namespace SomeName
{
[Application]
public class App : Application
{
public string Name { get; set;}
public App (IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public override void OnCreate ()
{
base.OnCreate ();
Name = "";
}
}
}
And you can access the data with:
App application = (App)Application.Context;
application.Name = "something";
I choose to do this on the Application calss because this class is called on the App startup so you don't have to initiate it manually.
Keep in mind that variables which are scoped to the Application have their lifetime scoped to the application by extension.
This class will be Garbage Collected if the Android feels it is necessary so you have to modify the code to include this case also.
You can use SharedPreferences or a Database to save your variables in case they get deleted and retrieve them from the App class for faster results.
Don't be overly wasteful in how you use this approach though, as attaching too much information on this class it can lead to a degradation in performance. Only add information that you know will be needed by different parts of the application, and where the cost of retrieving that information exceeds the cost of storing it as an application variable.
Investigate which information you need to hold as application wide state, and what information can simply be retrieved straight from your database. There are cost implications for both and you need to ensure you get the balance right.
And don't forget to release resources as needed on OnStop and OnDestroy
I rarely use intents, i find this way better.

getting Context from Intent

I have an Activity StaggeredPrenotaTour starting a second Activity Details through an Intent, the class Details contains an AsyncTask class ReservationTask, and after some operations to the network, it has to pass a Java Object back go the StaggeredPrenotaTour class.
StaggeredPrenotaTour at the point where it starts Details:
Intent message = new Intent(staggeredPrenotaTour, Details.class);
message.putExtras(bundle);
getContext().startActivity(message);
Basically I need pass my Object to the current context of StaggeredPrenotaTour, so that I don't have to create a new instance of it but update the contents of the current one!
Unfortunately I've read that there is no way you can get a Context from an Intent, so how is another way to get the working instance of StaggeredPrenotaTour inside Details class?
so how is another way to get the working instance of StaggeredPrenotaTour inside Details class?
You don't.
so that I don't have to create a new instance of it but update the contents of the current one!
It sounds like these two activities should share a common data model, perhaps implemented via a singleton manager. StaggeredPrenotaTour can use the revised data in its onResume() method, which will be called as part of it coming back into the foreground after Details is destroyed (e.g., user presses BACK).
Or, use an event bus (LocalBroadcastManager, greenrobot's EventBus, Square's Otto, etc.). Have ReservationTask raise a ReservationResultsEvent that StaggeredPrenotaTour subscribes to, so StaggeredPrenotaTour can find out the results of the work.
Starting another activity doesn't have to be one-way. You can also
start another activity and receive a result back. To receive a result,
call startActivityForResult() (instead of startActivity()).
For details, read the guide on developer.android.com

access sharedpreferences in class without passing context

I have a SyncAdapter overloading onPerformSync. In that method, I'd like to access sharedpreferences to get and put settings. As I understand it, for that I need access to a context. The SyncAdapter onPerformSync has a bundle argument, and maybe I could send the context that way.
In a similar problem, I have another base class (not a service or activity) for which I'm also interested in using sharedPreferences. For this, I would either need to pass the context to a method in the class, or instantiate it with the context that is then saved as a private member.
In both of these cases, I understand that keeping and using a context beyond the lifecycle of the activity or service associated with the context can lead to memory leaks.
In my case, my application can begin with either a broadcastreceiver or the main activity. The broadcast receiver starts a background process, and the main activity just starts the main activity. Whichever opens first registers periodic SyncAdapter updates and opens the other class. So if I were to pass the context of the calling activity or service, what happens if either one of them then closes? The SyncAdapter or base class would use an outdated context, and...memory leak? Or would the context revert to whatever remains running?
I also saw the solution to this: (Static way to get 'Context' on Android?), but would that fix anything? I'd then have an activity context, an application context, and a service context. Same problem right? The SyncAdapter may end up holding on to a context that has closed, no?
Based on the first answer here (SharedPreferences application context vs activity context) I'm tempted to go with the application singleton listed in the previous link, but I want to make sure. Thanks
I think what you want to do is to create a Service to manage the SyncAdapter like mentioned here. That way, the Context passed to the Service should be valid while the SyncAdapter is running.
The link shows that you would pass Service.getApplicationContext() to the SyncAdapter constructor. Then you could store that Context as a field in the SyncAdapter and use it when you need to. That Context should be valid for as long as you need it.
When the app and / or the SyncAdapter get GC'd, they should build a new SyncAdapter with a new Context the next time you need it.

In which cases getApplicationContext() function is used

I am following some tutorials for learning android but the problem is they do not contain all the details.
Specifically, it would be great if some light could be shed upon the use cases for getApplicationContext().
You can think of a Context as a handle to your application's resources (i.e. everything in the res folder) and to the Android runtime. Classes like Activity, Service, Application inherit from Context, among others.
Typically, you'll pass in the current Activity whenever a Context is required, since Activity inherits from Context.
You'll also find information about using getApplicationContext() instead of your activities when a Context is required. This usually is to prevent whatever code that needs the Context from unnecessarily holding a reference to your Activity, which in the worst case might preventing it from being garbage collected (passing in the Application isn't really a huge problem in that scenario, because it's expected to be around for a long time).
However, there are certain scenarios where an argument of a method is of type Context, but an Activity is actually required. Using startActivity() is one example of this I believe (correct me if I'm wrong).

Android Context object how to handle

This is not a question about Context object itself. I wonder what the best way to manage reference to it. When I create android objects like Activity, Service, etc - context already accessible everywhere.
But I have bunch of different classes for data access, various shared utilities, etc. I find myself writing every call and passing context alone. I wonder if there any good way to deal with context. Maybe static? Is that good idea to store reference in my own Application object like so?
public class MyApplication extends Application
{
public static Context Context;
This way I can access context from anywhere in application. Does it seem like a good idea?
Make public static Context mContext; as a global variable, and at the start of onCreate(), add mContext = this;. It makes access much easier. By making it public and static, other files can see the context of your main activity, and you won't have to pass it as a parameter to any function. In my opinion, this is probably the best/easiest way to manage reference to it. It also unclutters all sorts of references to MainActivity.this.
alextsc's comment shows a helpful link to problems that can occur from this as well.

Categories