What is the difference between starting ActivityB from ActivityA using
1. startActivity(this, ActivityB.class);
versus
2. startActivity(getApplicationContext(), ActivityB.class);
I typically see 1. used more often in examples, but I haven't come across a reason for why this is the case.
Reference to Activity as a Context (this) might become obsolete if your Activity goes through configuration changes, like rotation, and is destroyed and created again. Context recieved by getApplicationContext(), however, persists through lifetime of the process.
However, It seems to me it only is an issue when you bind Activity to Service or other similar scenario, so it's safe to use this when you use it in intent to start another Activity.
There is no difference. According source code of Intent and ComponentName - only thing, that used form context - is getting package name by context.getPackageName(). Package name is the same for Activity.this and Activity.getApplicationContext(), so there is no difference.
I assume you are actually asking about the difference between
startActivity(new Intent(this, ActivityB.class));
and
startActivity(new Intent(getApplicationContext(), ActivityB.class));
There is no difference. Android needs the ComponentName (package name and class). The context is used to determine the package name.
Related
I been told that starting activity from application context is bad idea, and you should prefer using activity context where possible.
Intent intent = new Intent(appContext, MyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
appContext.startActivity(intent);
So I read Google article about tasks: Tasks and Back Stack.
It says that each stack got its taskAffinity id, and if new activity will be lunched with taskAffinity id that belong to already running task, than it will be placed in that task(if lunch mode is default or single top).
So if you didn't declare taskAffinity id for your activity, it will not matter if you lunching your activity from app context or activity context.
But once again, I been told that using app context to start new activity is a bad practice. So please tell me, why is that so? Do I missing important cases where I should pay attention to?
The constructor of a pending intent needs an Intent object in it from the current context to the next activity. In my app, I have only a single activity containing multiple Views. No Second Activity.
The Views are Destroyed or made visible on demand. Obviously I cannot add a View to the constructor of an intent. So how shall I direct the pending intent? Multiple views have been accommodated into the main.xml using the <include/> command.
This is very easy to accomplish. mvnpavan already gave you good hint, you just need to do some additional work. First of all you should get familiar with this page http://developer.android.com/guide/components/tasks-and-back-stack.html.
It explains how to manage your application tasks and back stack. In your case you have 2 options:
1.Configure launchMode property of Activity in manifest. Setting singleTop should do the job since your are using just one activity.
<activity
android:name="com.yourpackage.YourClass"
android:launchMode="singleTop">
</activity>
2.Add flag FLAG_ACTIVITY_SINGLE_TOP to your Intent(the one you are passing to PendingIntent):
Intent intent = new Intent(this, YourActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Please note that in both cases you can implement callback method of you activity onNewIntent(). Use it in case you wish to do some extra work when app is bring back to the foreground.
Update:
Regards keeping connection to the server I would use Service, not Activity. Then you can do whatever you like with your activity. This is the best practise. If you worry that Activity has no direct access to the Service API, you can bind to that Service. Have a look at this page http://developer.android.com/guide/components/bound-services.html You can just copy/paste the code and your are done. It's very easy to maintain. In the future you may need to create another activity which require connection to the server. It will save you a lot of time and headaches :).
Use pending intent to resume your application and not recreate it like this:
Intent i = new Intent(this, youractivity.class);
pIntent = PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
Hope it helps! ;)
When I have e.g. a custom service and a custom activity in the same ADT project, then I can use this in the service, to start my activity:
Intent i = new Intent(context, MyCustomActivity.class);
startActivity(i);
However when I have the service and activity in separate projects, then I cannot do this since I do not have a direct reference to MyCustomActivity.class. This is problematic: I do not wish to include a JAR just to be able to fix that broken reference, since I assume this will increase the package size and create redundant data on the device (i.e. activity code is duplicated between the service and activity packages). So instead, I use this (perhaps there are other options?):
Intent i = new Intent("com.mypackage.myStringActionName");
startActivity(i); //is this a broadcast?
OR
Intent i = new Intent("com.mypackage.myStringActionName");
sendBroadcast(i);
...But I don't really like sending broadcasts when all I want is to direct the intent to a single activity to tell it to start.
So, what other ways are there to go about avoiding duplication (in ADT)? Or else a better way to send direct intents?
you can try this:
Intent i = new Intent();
i.setComponent(new ComponentName(packageName, classname));
startActivity(i);
the className must contains the packageName and main activity name
I am calling an activity from another activity by this code:
Intent intent = new Intent(context, mClass);
context.startActivity(intent);
and from my new activity which is started by this code. I want to know which activity starts this activity. I used this code for this purpose
Intent intent = getIntent();
Class<?> c = intent.getClass();
if (c != OffersActivity.class) {
prepareForNotifications();
setListAdapter();
}
but by this code I am not able to get the classname which starts this activity. I really need some help.
thanks
There is a method getCallingActivity(), but that only works, if the calling activity calls you with startActivityForResult(). I have seen libraries use that and say that you must call them that way, but frankly it is a bit nasty. The simple answer is that you're not supposed to know. Android is a system of loosely coupled activities and the calling activity should thus have no real meaning to your activity. Any information your activity needs should be put explicitly in the intent, so if you really want to know who called you then the caller needs to put that extra in. You won't be able to tell if they are lying of course, so don't go trying to use this for anything security-related. However, I would suggest that whatever you're determining based on the caller, is what the caller should be passing you instead. Might be time for a rethink on why you want to do this, since trying to fight the system will only lead to pain.
I would suggest:
public static final String INTENTSENDER = "sender";
void mMethod() {
Intent intent = new Intent(context, mClass);
intent.putExtra(INTENTSENDER, mClass);
context.startActivity(intent);
}
knowing who sent it:
Class<?> c = (Class<?>)intent.getExtras().get(INTENTSENDER);
However, you can also use this:
ComponentName componentName = this.getCallingActivity();
Now, you can use componentName to get the sender of the intent.
Maybe it's best to use the extras parameters in the intent when you call them...like: Intent.putExtra(PARAM,value) on the caller activity...and on the opened activity you check:
intent.getStringExtra(PARAM)
getParentActivity() is not what yout are looking for?
Is there a way to set parameters that they would receive as arguments in the constructor were they initialized as standard objects instead of by intents? I can't use parameters stored in the intent because sending an intent doesn't necessarily initialize the activity / service (it may exist already). Can I use the manifest file to set custom parameters?
Thanks.
Starting an Activity will always start activity, and if activity is already in stack, then also it would launch the activity, unless some intent filter havent been specified.
For Service, if you start service by startService(), onStartCommand() method will be invoked, which has an Intent as parameter, you can get values passed from this parameter.
sending an intent doesn't necessarily initialize the activity / service(it may exist already).
What if you keep using Intents but erase the history of the TargetActivity each time you call it.
Intent intent = new Intent(this,TargetActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
I found a possible solution here: Is it possible to have custom attributes in AndroidManifest.xml tags?
Doesn't help if I want to pass objects, but for simple types it's good enough.