An Intent is a passive data structure that carries information from one Activity to another. An Intent is also capable of holding data in the form of name-value pairs (via putExtra()).
But while overriding the onCreate() method we pass a Bundle as the parameter, which ultimately also holds values in the form of name-value pairs and is able to store information with the help of onSaveInstanceState().
In such a scenario why do we need both and what differentiates the two?
I suppose I have led you guys into a misbelief that I have misunderstood what an Intent is:
When I said "An Intent is a passive data structure that carries information from one Activity to another", what I intended to point out was that even an Intent can carry information (other than the context and action description) with the help of putExtra() method. Why do we need to use a Bundle then?
I think you already have understood what a Bundle is: a collection of key-value pairs.
However, an Intent is much more. It contains information about an operation that should be performed. This new operation is defined by the action it can be used for, and the data it should show/edit/add. The system uses this information for finding a suitable app component (activity/broadcast/service) for the requested action.
Think of the Intent as a Bundle that also contains information on who should receive the contained data, and how it should be presented.
From the source of Intent class, there really is no difference between the two. Check below code from Intent class:
public Intent putExtra(String name, String value) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putString(name, value);
return this;
}
And
public Intent putExtras(Bundle extras) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putAll(extras);
return this;
}
So I think, only difference is ease of use.. :) for 1st, you don't need to create your bundle explicitly.
Intent facilitate communication between components.Intent is the message that is passed between components such as activity.
that can be used intent.putExtra(Key,value) and intent.putExtra(Bundle)
Intent intent = new Intent();
intent.setClass(this, Other_Activity.class);
// intent.putExtra(key,value)
intent.putExtra("EXTRA_ID", "SOME DATAS");
startActivity(intent);
Using Bundle : For example
Bundle bundle=new Bundle();
bundle.putString("Key","Some value");
intent.putExtras(bundle);
startActivity(intent);
Call the bundle in another activity :
Bundle extras=getIntent().getExtras();
extras.getString(key);
I really don't know from where you got this definition for Intent, but as an 'Intent' definition
An intent is an abstract description of an operation to be performed.
It can be used with startActivity to launch an Activity,
broadcastIntent to send it to any interested BroadcastReceiver
components, and startService(Intent) or bindService(Intent,
ServiceConnection, int) to communicate with a background Service.
An Intent provides a facility for performing late runtime binding
between the code in different applications. Its most significant use
is in the launching of activities, where it can be thought of as the
glue between activities. It is basically a passive data structure
holding an abstract description of an action to be performed.
So Intent is an action to link to new (Activity, Service, BroadCastReceiver)
In Intent you will find a definition for Extras
extras -- This is a Bundle of any additional information. This can be used to provide extended information to the component. For example, if we have a action to send an e-mail message, we could also include extra pieces of data here to supply a subject, body, etc.
So that means Extras in the Intent is an object of A Bundle
Going to Bundle as you mentioned it is a carrier for data from one Intent to another and is a map of Key-Value variables.
Related
I am new to Android development and I have come across something new while using Intent as getIntent().getExtras().
Can anyone please explain me how can we write getIntent().getExtras(),cause till now what I know is we can call method by creating object of that particular class but here we are call method getExtras() by using getIntent()method.
getIntent().getExtras() is used to get values from intent that are stored in bundle.
Intent class is used to switch between activities. But sometimes we need to send data from one activity to another. So, at this particular moment we need to set some values to intent that can be transferred to destination activity. We can achieve this by the following code -
Bundle bundle = new Bundle();
bundle.putString("key1","someValue");
Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
intent.putStringExtra("key","value");
intent.putExtras(bundle);
startActivity(intent);
Now, in the second activity we can get the value of "key" so we can use that in second activity. To do so, we use the getIntent().getIntent can store a Bundle. Let's see an example -
Intent intent=getIntent();
Bundle valueFromFirstActivity = intent.getExtras();
String valueOfKey = intent.getStringExtra("key");
String valueOfKey = bundle.getString("key1");
So this way, one can get values from activities. Bundle is a class that can hold values within itself and that instance of bundle can be given to intent using putExtras(). It is quite helpful in transferring the custom array list.
we can call method by creating object of that particular class
getIntent() is a method that returns an Intent object. When you call getIntent().getExtras(), first an Intent object is returned and then getExtras() method is invoked.
This way of calling is referred to as method chaining(Fluent Interfaces)
The Android docs define an Intent as "a bundle of information containing an abstract description of an operation to perform". This suggests that you should be able to reuse a single Intent object multiple times if needed, but I haven't seen any examples showing this is the case/ is safe to do. Is there any reason to NOT do the following:
private final Intent enableBluetoothIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
...
protected void onCreate(Bundle savedInstanceState) {
enabledBluetoothIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
...
}
and then call startActivityForResult(enableDiscoverableIntent, REQUEST_ENABLE_BT_DISCOVERY) in multiple places in the code? What happens if the same intent is started twice?
It is completely safe when you want to use it to do the exact same thing, since an Intent is no more than a bunch of data and instructions. If you want to use the same Intent object for different purposes (for example you have a bunch of tabs and try to set the tabs reusing the same intent but changing the activity they'll launch) you have to be more careful, and I'd recommend re-creating a new Intent object for each.
I am a newbie on Android development and how data pass from one activity to another is still unclear for me.
Is it a good practice to pass your own objects between activities?
Which size could they have?
EDIT:
Maybe I did not explained it clearly. I know how to pass data between activities. The question is: Is it a good practice or should I better obtain data from SQLlite database? In that case, which is the maximun size I can pass to have a good performance?
Sending object is same as sending pre defined objects like String or variables,it can be done by binding your object to Intent by using putParceble() or putSerializable() methods directly on intent or by binding object to a bundle object.
But u have to make sure that your class implement either Parcelable or Serializable.
like here:
UserDefined myObject=new UserDefined();
Intent i = new Intent(this, Activity2.class);
Bundle b = new Bundle();
b.putParcelable("myObject", myObject);
i.putExtras(b);
startActivity(i);
And in receiving activity:
Bundle b = this.getIntent().getExtras();
myObject = b.getParcelable("myObject");
you can also send object without using Bundle:
Intent i=new Intent(PicActivity.this,PostPhotoActivity.class);
i.putExtra("myObject", myObject);
startActivity(i);
on receivingActivity:
UserDefined myObj=(UserDefined)getIntent().getParcelableExtra("myObject");
In Android parcelable is prefered instead of serializable.
Bundle extras = intent.getExtras();
if (extras != null) {
Toast.makeText(context, "Message recieved", Toast.LENGTH_SHORT).show();
}
What is the value stored in extras.. :?
The values stored in extras are the values you put into the extras.
To add an extra to an intent, do the following before you start it.
intent = new Intent(v.getContext(),TextActivity.class);
intent.putExtra("Title", "I am An extra");
startActivityForResult(intent, -1);
Then in your intent, to read it do:
String title = getIntent().getStringExtra("Title");
The code in your question is just posting a popup message if there is an extra found.
Currently you do not add anything to extras.
Extras is a Bundle, so it'll usually hold a collection of values. From your code fragment, it is impossible to tell what is in there. It depends on what the code that created the intent put into the bundle.
If you want to know all keys in a Bundle, use Bundle.keySet().
Regarding your remark, there is no true "beginning of a program" in an Android application. Your activity is marked in the manifest as the 'launcher' activity. If your activity is started from the Launcher, the Extras will be empty. However, no-one is stopping you (or other applications) from starting your activity manually, providing data in the extras.
There is no magic involved here. If you don't put anything into the Extras, nothing comes out.
How can I extract all information about an intent? Like action, extras, bundles etc.
Intent intent = getIntent();
Log.d(Tag.getTag(this), (/*What shall I add here?*/));
intent.getAction(), intent.getData(), intent.getExtras(), and maybe others. All of these are documented in the Intent class.
If you are using toString() method, you can see something like,
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.test/.TestDeleteActivity }
What I suggest is, if you want details about your running Intent, use the appropriate methods. As an example by using getPackage() method you can retrieve the application package name this Intent is limited to. The documentation contains all the methods you can use with Intent class.
If you want to pass some data from one Intent to another, use the Bundle class. This link will show you a simple example of how to use Bundle class.