史上最全干货:Android中的Intent
来源:互联网 发布:英雄无敌2 for mac 编辑:程序博客网 时间:2024/06/05 10:07
Intent
Intents are small messages that can be passed around the Android system. These messages hold information about our intention to perform some task.
From Android developers: It is basically a passive data structure holding an abstract description of an action to be performed.
Getting a result from another Activity
By using startActivityForResult(Intent intent, int requestCode)
you can start another Activity and then receive a result from that Activity in the onActivityResult(int requestCode, int resultCode, Intent data)
method. The result will be returned as an Intent.
In this example MainActivity will start a DetailActivity and then expect a result from it. Each request type should have its own int request code, so that in the overridden onActivityResult(int requestCode, int resultCode, Intent data) method in MainActivity , it can be determined which request to process by comparing values of requestCode and REQUEST_CODE_EXAMPLE (though in this example, there is only one).
MainActivity:
public class MainActivity extends Activity {
// Use a unique request code for each use case private static final int REQUEST_CODE_EXAMPLE = 0x9345; @Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Create a new instance of Intent to start DetailActivity final Intent intent = new Intent(this, DetailActivity.class); // Start DetailActivity with the request code startActivityForResult(intent, REQUEST_CODE_EXAMPLE);}// onActivityResult only get called // when the other Activity previously started using startActivityForResult@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // First we need to check if the requestCode matches the one we used. if(requestCode == REQUEST_CODE_EXAMPLE) { // The resultCode is set by the DetailActivity // By convention RESULT_OK means that whatever // DetailActivity did was executed successfully if(resultCode == Activity.RESULT_OK) { // Get the result from the returned Intent final String result = data.getStringExtra(DetailActivity.EXTRA_DATA); // Use the data - in this case, display it in a Toast. Toast.makeText(this, "Result: " + result, Toast.LENGTH_LONG).show(); } else { // setResult wasn't successfully executed by DetailActivity // Due to some error or flow of control. No data to retrieve. } }}}
A few things you need to be aware of:
Data is only returned once you call finish(). You need to call setResult() before calling finish(), otherwise, no result will be returned.
Make sure your Activity is not using android:launchMode=”singleTask”, or it will cause the Activity to run in a separate task and therefore you will not receive a result from it. If your Activity uses singleTask as launch mode, it will call onActivityResult() immediately with a result code of Activity.RESULT_CANCELED.
Be careful when using android:launchMode=”singleInstance”. On devices before Lollipop (Android 5.0, API Level 21), Activities will not return a result.
You can use explicit or implicit intents when you call startActivityForResult(). When starting one of your own activities to receive a result, you should use an explicit intent to ensure that you receive the expected result. An explicit intent is always delivered to its target, no matter what it contains; the filter is not consulted. But an implicit intent is delivered to a component only if it can pass through one of the component’s filters.
Passing data between Activites
This example illustrates sending a String with value as “Some data!” from OriginActivity to DestinationActivity.
OriginActivity
public class OriginActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_origin); // Create a new Intent object, containing DestinationActivity as target Activity. final Intent intent = new Intent(this, DestinationActivity.class); // Add data in the form of key/value pairs to the intent object by using putExtra() intent.putExtra(DestinationActivity.EXTRA_DATA, "Some data!"); // Start the target Activity with the intent object startActivity(intent);}}
DestinationActivity
public class DestinationActivity extends AppCompatActivity {
public static final String EXTRA_DATA = "EXTRA_DATA";@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_destination); // getIntent() returns the Intent object which was used to start this Activity final Intent intent = getIntent(); // Retrieve the data from the intent object by using the same key that // was previously used to add data to the intent object in OriginActivity. final String data = intent.getStringExtra(EXTRA_DATA);}}
It is also possible to pass other primitive data types as well as arrays, Bundle and Parcelable data. Passing Serializable is also possible, but should be avoided as it is more than three times slower than Parcelable.
Serializable is a standard Java interface. You simply mark a class as Serializable by implementing the Serializable interface and Java will automatically serialize it during required situations.
Parcelable is an Android specific interface which can be implemented on custom data types (i.e. your own objects / POJO objects ), it allows your object to be flattened and reconstruct itself without the destination needing to do anything.
Once you have a parcelable object you can send it like a primitive type , With an intent object:
intent.putExtra(DestinationActivity.EXTRA_DATA, myParcelableObject);
Or in a bundle / as an argument for a fragment
bundle.putParcelable(DestinationActivity.EXTRA_DATA, myParcelableObject);
and then also read it from the intent at the destination using getParcelableExtra :
final MyParcelableType data = intent.getParcelableExtra(EXTRA_DATA);
Or when reading in a fragment from a bundle :
final MyParcelableType data = bundle.getParcelable(EXTRA_DATA);
Once you have a Serializable object you can put it in an intent object :
bundle.putSerializable(DestinationActivity.EXTRA_DATA, mySerializableObject);
and then also read it from the intent object at the destination as shown below:
final SerializableType data = (SerializableType)bundle.getSerializable(EXTRA_DATA);
Open a URL in a browser
Opening with the default browser
public void onBrowseClick(View v) {String url = "http://www.google.com";Uri uri = Uri.parse(url);Intent intent = new Intent(Intent.ACTION_VIEW, uri);// Verify that the intent will resolve to an activityif (intent.resolveActivity(getPackageManager()) != null) { // Here we use an intent without a Chooser unlike the next example startActivity(intent);} }
Prompting the user to select a browser
Note that this example uses the Intent.createChooser() method:
public void onBrowseClick(View v) {String url = "http://www.google.com";Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));// Note the Chooser below. If no applications match, // Android displays a system message.So here there is no need for try-catch.startActivity(Intent.createChooser(intent, "Browse with"));}
In some cases, the URL may start with “www”. If that is the case you will get this exception:
android.content.ActivityNotFoundException : No Activity found to handle Intent
The URL must always start with “http://” or “https://”. Your code should therefore check for it, as shown in the following code snippet:
if (!url.startsWith("https://") && !url.startsWith("http://")){url = "http://" + url;}Intent openUrlIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));if (openUrlIntent.resolveActivity(getPackageManager()) != null) {startActivity(openUrlIntent);}
Best Practices
Check if there are no apps on the device that can receive the implicit intent. Otherwise, your app will crash when it calls startActivity(). To first verify that an app exists to receive the intent, call resolveActivity() on your Intent object. If the result is non-null, there is at least one app that can handle the intent and it’s safe to call startActivity(). If the result is null, you should not use the intent and, if possible, you should disable the feature that invokes the intent.
Making a custom object Parcelable
public class Foo implements Parcelable
{
private final int myFirstVariable;
private final String mySecondVariable;
private final long myThirdVariable;
public Foo(int myFirstVariable, String mySecondVariable, long myThirdVariable){ this.myFirstVariable = myFirstVariable; this.mySecondVariable = mySecondVariable; this.myThirdVariable = myThirdVariable;}// Note that you MUST read values from the parcel IN THE SAME ORDER that// values were WRITTEN to the parcel! This method is our own custom method// to instantiate our object from a Parcel. It is used in the Parcelable.Creator variable we declare below.public Foo(Parcel in){ this.myFirstVariable = in.readInt(); this.mySecondVariable = in.readString(); this.myThirdVariable = in.readLong();}// The describe contents method can normally return 0. It's used when// the parceled object includes a file descriptor.@Overridepublic int describeContents(){ return 0;}@Overridepublic void writeToParcel(Parcel dest, int flags){ dest.writeInt(myFirstVariable); dest.writeString(mySecondVariable); dest.writeLong(myThirdVariable);}// Note that this seemingly random field IS NOT OPTIONAL. The system will// look for this variable using reflection in order to instantiate your// parceled object when read from an Intent.public static final Parcelable.Creator<Foo> CREATOR = new Parcelable.Creator<Foo>(){ // This method is used to actually instantiate our custom object // from the Parcel. Convention dictates we make a new constructor that // takes the parcel in as its only argument. public Foo createFromParcel(Parcel in) { return new Foo(in); } // This method is used to make an array of your custom object. // Declaring a new array with the provided size is usually enough. public Foo[] newArray(int size) { return new Foo[size]; }};}
- 史上最全干货:Android中的Intent
- Android中的intent
- 【转】Android中的Intent
- Android中的Intent
- Android中的Intent
- Android中的Intent
- Android中的Intent总结
- Android中的Intent
- Android 中的Intent
- android中的intent
- Android中的Intent
- Android中的Intent
- android 中的意图intent
- Android中的Intent详解
- Android 中的 Intent
- android中的intent
- Android中的intent
- android中的activity---intent
- [日常学习][C++]集合 set
- 缓存的主键的生成策略
- XTUExper数值计算方法 C语言实现
- Java经典算法大全(一)
- 响应式编程笔记
- 史上最全干货:Android中的Intent
- input子系统框架、核心层、输入事件驱动层详解
- C语言求二维数组a所有偶数元素之和
- js中的构造函数,原型,原型链,继承
- windows安装Apache,注册服务出现“(OS 5)拒绝访问。 : AH00369: Failed to open the WinNT service manager..."
- 背包、队列和栈
- PHP 获取一段时间内列表
- 类的继承习题
- 好RESTful API的设计原则