• android ——Intent


    Intent是android程序中各组件之间进行交互的重要方式,它可以用于指明当前组件想要执行的动作,也可以在不同组件之间传递数据,Intent一般被用于启动活动,启动服务以及发送广播。

    一、显式的使用Intent启动活动

    Intent有多个构造函数的重载,其中有Intent(Context packageContext, Class<?>cls ),第一个参数Context指定了启动活动的上下文,第二个参数指定了想要启动的目标活动

    Intent intent = new Intent(MainActivity.this,Main2Activity.class);
    startActivity(intent);

    先创建一个Intent对象,指定想要启动的目标活动,然后调用startActivity()方法根据参数intent对象启动这个活动。

    二、隐式的使用Intent启动活动

    隐式Intent它并不明确的指示想要启动那一个活动,而是指定了一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent再去启动合适的活动

    先创建一个自定义action和category的活动在AndroidManifest中:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="xbt.exp19">
    
        <application
    ...
            </activity>
            <activity android:name=".Main2Activity">
                <intent-filter>
                    <action android:name="XX"/>
                    <category android:name="android.intent.category.DEFAULT"/>
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

    这里随意设定了XXv这个action,然后android.intent.category.DEFAULT是一种默认的category,所以调用的时候:

      Intent intent = new Intent("XX");
      startActivity(intent);

    Intent的参数就是一个XX的字符串,指定了想要启动的活动的action信息,然后startActivity()方法会自动的把默认的category信息添加到intent中

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="xbt.exp19">
    
        <application
    ...
            </activity>
            <activity android:name=".Main2Activity">
                <intent-filter>
                    <action android:name="XX"/>
                    <category android:name="android.intent.category.DEFAULT"/>
                    <category android:name="ww"/>
                    <category android:name="xw"/>
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

    这里额外添加了两个category,因为category是可以增加任意多个的,然后使用的时候:

      Intent intent = new Intent("XX");
      intent.addCategory("ww");
      intent.addCategory("xw");
      startActivity(intent);

    这样使用就行,要注意的地方有:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="xbt.exp19">
    
        <application
    ...
            </activity>
            <activity android:name=".Main2Activity">
                <intent-filter>
                    <action android:name="XX"/>
                    <category android:name="ww"/>
                    <category android:name="xw"/>
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

    这样就会出错,因为startActivity()方法会自动的把默认的category信息添加到intent中所以category默认的那一个信息必须得加上,,不过我没查过资料,,反正我手机必须加上。。

    然后使用一下系统设定的action:

      Intent intent1 = new Intent(Intent.ACTION_VIEW);
      intent1.setData(Uri.parse("http://www.baidu.com"));
       startActivity(intent1);

    这样就能启动浏览器,并打开百度。

     Intent intent2 = new Intent(Intent.ACTION_DIAL);
     intent2.setData(Uri.parse("tel:10086"));
    startActivity(intent2);

    这样就能打开拨号盘,并且已经输入好10086。

    三、使用Intent传递数据

    1、向下一个活动传递数据

      Intent intent = new Intent(MainActivity.this,Main2Activity.class); 
      intent.putExtra("id",1); 
      intent.putExtra("name","名字");  
      intent.putExtra("age",20.5f); 
      startActivity(intent); 

    接收的时候:

      Intent intent = getIntent();
      String name = intent.getStringExtra("name");
      int id =intent.getIntExtra("id");
      float age = intent.getFloatExtra("age");

    发送的时候使用的putExtra()第一个参数相当于发送的数据的键,第二个参数是发送的实际值,接受的时候就是根据这个键,然后相应的类型要使用不同的方法接收数据。

    2、返回数据给上一个活动

    a、主活动中创建用于启动目标活动的Intent对象。

    b、调用startActivityForResult()方法启动目标活动。

    c、被启动的活动创建一个Intent对象,并调用putExtra()方法将要传递的数据存放在intent中。

    d、调用setResult()方法返回数据,然后调用finish()销毁该活动。

    e、在主活动中重写onActivityResult()方法,在其中保存接受到的数据

    主活动中的启动目标活动的代码:

    button1.setOnClickListener(new View.OnClickListener(){
        public void onClick(View v){
            Intent intent = new Intent(MainActivity.this,SecondActivity.class);
            startActivityForResult(intent,1);
        }
    });

    startActivityForResult()的第二个参数是一个请求码,要求是一个唯一值。

    被启动的活动中的返回数据的代码:

    button2.setOnClickListener(new View.OnClickListener(){
        public void onClick(View v){
            Intent intent = new Intent();
            intent.putExtra("data_return","first");
            setResult(RESULT_OK,intent);
            finish();
        }
    });

    setResult()方法第一个参数用于向上一个活动返回处理结果,一般使用RESULT_OK或RESULT_CANCELED两个值,第二个参数把带有数据的Intent传递出去。

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode){
            case 1:
                if (requestCode == RESULT_OK){
                    String returnedData = data.getStringExtra("data_return");
                    Log.d("MainActivity",returnedData);
                }
                break;
            default:
        }
    }

    由于我们使用的startActivityForResult方法来启动SecondActivity的,在SecondActivity销毁后会回调上一个的onActivityResult方法,因此就需要重写这个方法

    onActivityResult有三个参数,第一个参数是我们启动活动时传入的请求码,第二个参数resultCode即我们返回数据时传入的处理结果,第三个参量,即携带着返回数据的Intent。

    在一个活动中我们可能利用startActivityForResult启动很多不同的活动,每一个返回的数据都会回调到onActivityResult这个方法中,我们首先要检查的就是requestCode的值来判断数据来源,再通过resultCode检查处理结果是否成功。

    四、使用Intent传递对象

    想要使用使用Intent传递对象就是要把对象序列化,变得可存储可传输的状态然后才能使用Intenti传输,目前有Serializable 和Parcelable两种方式,Serializable相对Parcelable实现简单,但是效率低一些。

    Serializable:

    假如有这样一个Fruit对象把它序列化:

     1 public class Fruit implements Serializable {
     2     private String name;
     3 
     4     private int imageId;
     5 
     6     public Fruit(String name,int imageId){
     7         this.name = name;
     8         this.imageId = imageId;
     9     }
    10 
    11     public String getName(){
    12         return name;
    13     }
    14 
    15     public int getImageId(){
    16         return imageId;
    17     }
    18 }

    然后在活动中传递的时候:

      Fruit fruit = new Fruit("orange",1)  
      Intent intent = new Intent(MainActivity.this,Main2Activity.class); 
      intent.putExtra("fruit",fruit); 
      startActivity(intent); 

    在目标活动中:

      Fruit fruit = (Fruit) getIntent().getSerializableExtra("fruit");

    Parcelable:

    这个就比较复杂了需要对整个对象进行分解

    比如这样一个Fruit对象把它序列化

    public class Fruit implements Parcelable {
        private String name;
    
        private int imageId;
        
        public String getName(){
            return name;
        }
    
        public int getImageId(){
            return imageId;
        }
    
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel parcel, int i) {
            parcel.writeString(name);
            parcel.writeInt(imageId);
        }
        
        public static final Parcelable.Creator<Fruit> CREATOR = new Parcelable.Creator<Fruit>(){
            @Override
            public Fruit createFromParcel(Parcel parcel) {
                Fruit fruit = new Fruit();
                fruit.name = parcel.readString();
                fruit.imageId = parcel.readInt();
                return fruit;
            }
    
            @Override
            public Fruit[] newArray(int i) {
                return new Fruit[i];
            }
        };
    }

    重写describeContents()和writeToParcel()这两个方法。其中describeContents()方法直接返回0 就可以了,而writeToParcel()方法中我们需要调用Parcel的writeXxx()方法将Person 类中的字段一一写出。

    还必须在Person 类中提供一个名为CREATOR 的常量,接着需要重写createFromParcel()和newArray()这两个方法,在createFromParcel()方法中我们要去读取刚才写出的name 和Id字段,并创建一个fruit对象进行返回,其中name 和Id都是调用Parcel 的readXxx()方法读取到的,注意这里读取的顺序一定要和刚才写出的顺序完全相同。而newArray()方法中的实现就简单多了,只需要new 出一个Fruit数组,并使用方法中传入的size 作为数组大小就可以了。

    目标活动中这样写:

    Fruit fruit = (Fruit) getIntent().getParcelableArrayExtra("fruit");
  • 相关阅读:
    Android--Activity中使用Intent传值
    Android--使用剪切板在Activity中传值
    Android--通过Application传递数据
    HTTP 头缓存Last-Modified,ETag,Expires
    HTTP请求头 If-Modified-Since
    HTML5 本地存储形式
    spring作用域(Spring Bean Scopes Example)
    java.sql.SQLException: Data truncation: Truncated incorrect DOUBLE value
    对hadoop 执行mapreduce时发生异常Illegal partition for的解决过程
    InnerHTML属性的XSS利用
  • 原文地址:https://www.cnblogs.com/xxbbtt/p/7488130.html
Copyright © 2020-2023  润新知