Intent使用

1)使用显式Intent在活动之间穿梭

    从MainActivity 跳到 SecondActivity :

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

2)使用隐式Intent在活动之间穿梭

    不明确指出启动哪个活动,而是指定一系列更为抽象的action、category等信息,然后交由系统去分析这个Intent,找出合适的活动去启动。

    在创建一个Empty Activity后,在默认情况下,会在清单文件中添加的配置如下:

<activity android:name=".SecondActivity"></activity>

a) 使用默认的category

    对其进行修改如下:

<activity android:name=".SecondActivity">
   <intent-filter>
      <action android:name="com.example.intenttest.ACTION_START" />
      <category android:name="android.intent.category.DEFAULT" />
   </intent-filter>
</activity>

    在 <action> 标签中指明当前活动可以响应 com.example.intenttest.ACTION_START 这个action,<category>标签则包含了一些附加信息,更准确指明了当前的活动能够响应的Intent中还可能带有的category;
只有 <action>和<category>同时匹配intent中指定的action和category时,才能响应该Intent.
    这里添加的category是一个默认的的category,在调用startActivity方法时自动将这个category添加到category中。

    进行跳转:

Intent intent = new Intent("com.example.intenttest.ACTION_START");
startActivity(intent);

b) 指定category

    每个Intent只能指定一个action,但却能指定多个category,之前是设置的默认的category,再进行设置一个。

    在清单文件中添加对应的category:

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="com.example.intenttest.ACTION_START" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="com.example.intenttest.MY_CATEGORY" />
    </intent-filter>
</activity>

    指定对应的category:

Intent intent = new Intent("com.example.intenttest.ACTION_START");
intent.addCategory("com.example.intenttest.MY_CATEGORY");
startActivity(intent);

    如果清单文件和intent中category不匹配,就会崩溃掉!

3)隐式Intent调用系统应用

a) 使用系统浏览器打开网页

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

    指定action为Intent.ACTION_VIEW,这是Android系统内置的动作,其常量值为:android.intent.action.VIEW ,通过Uri.parse方法,将一个网址字符串解析成Uri对象,再调用Intent的setData方法将这个Uri对象传进去。
    setData接收Uri对象,用于指定当前Intent正在操作的数据,这些数据以字符串的形式传入到Uri.parse方法解析产生。

     <intent-filter>中可以配置 <data>标签,用于指定但前活动能够响应什么类型的数据:

-描述
android:scheme数据协议,如上面的http部分
android:host数据的主机名
android:port数据的端口
android:path指定主机名和和端口之后的部分,如一段网站中跟在域名之后的部分
android:mimeType处理的数据类型,允许使用通配符的方式指定

<data>标签指定的内容和Intent中携带的data完全一致时,当前活动才能响应Intent。

     在清单文件中修改SecondActivity的配置如下:

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="http" />
    </intent-filter>
</activity>

     SecondActivity能响应Intent为android.intent.action.VIEW 即 Intent.ACTION_VIEW的,SecondActivity和浏览器一样能够响应一个打开网页的Intent。

b) 使用系统的拨打电话

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

4)使用Intent向下一个活动传递数据

a) 传递字符串

     跳转时携带数据:

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("extra_data", "hello");
startActivity(intent);

     获取数据:

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        Intent intent = getIntent();
        if (intent != null){
            String data = intent.getStringExtra("extra_data");
            if (!TextUtils.isEmpty(data)){
                Log.d("AAAAAAAAAAA", data);
            }
        }

    }
}

     getIntent()可以获取到用于启动SecondActivity 的Intent,然后调用getStringExtra方法,传入键值得到传递的数据。

b) 传递int

     携带的数据:

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("extra_data", 123456);
startActivity(intent);

     获取数据:

Intent intent = getIntent();
if (intent != null){
    int data = intent.getIntExtra("extra_data", 0);
    Log.d("AAAAAA", "extra_data 为:"+data);
}

c) 传递图片

     携带的数据:

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("extra_data", R.mipmap.ic_launcher);
startActivity(intent);

     获取数据:

Intent intent = getIntent();
if (intent != null){
    int data = intent.getIntExtra("extra_data", 0);
    if (data != 0){
        Log.d("AAAAAA", "extra_data 为:"+data);
        ImageView test_iv = findViewById(R.id.test_iv);
        test_iv.setImageDrawable(getResources().getDrawable(data));
    }
}

d) 通过bundle传递数据

     携带的数据:

Bundle bundle = new Bundle();
bundle.putString("bundleData", "helloWorld");

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("extra_data", bundle);
startActivity(intent);

     获取数据:

Intent intent = getIntent();
if (intent != null){
    Bundle bundle = intent.getBundleExtra("extra_data");
    String bundleData = bundle.getString("bundleData");
    Log.d("AAAAAA", "bundleData 为:"+bundleData);
}

e) 通过serializable传递数据

Person类:

public class Person implements Serializable{
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

     携带的数据:

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("extra_data", new Person("zhangSan", 21));
startActivity(intent);

     获取数据:

Intent intent = getIntent();
if (intent != null){
    Person person = (Person) intent.getSerializableExtra("extra_data");
    Log.d("AAAAAA", person.getName() + " - "+person.getAge());
}

f) 通过Parcelable传递数据

Parcelable比serializable性能高,serializable是IO流的方式存储到磁盘,Parcelable是C++对象指针挪动保存数据。

Person类:

public class Person implements Parcelable {
    private String name;
    private int age;

    public Person(){}
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Person(Parcel in){
        name = in.readString();
        age = in.readInt();
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public int describeContents() {
        return 0;
    }
    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(name);
        parcel.writeInt(age);
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }
        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };
}

     携带的数据:

ArrayList<Person> list = new ArrayList<>();
list.add(new Person("zhangSan", 21));
list.add(new Person("LiSi", 22));

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("extra_data", list);
startActivity(intent);

     获取数据:

Intent intent = getIntent();
if (intent != null){
    ArrayList<Parcelable> extra_data = intent.getParcelableArrayListExtra("extra_data");
    for (int i=0; i < extra_data.size(); i++ ){
        Person person = (Person)extra_data.get(i);
        Log.d("AAAAAA", person.getName() + " - "+person.getAge());
    }
}

5)返回数据给上一个Intent

     第一个Activity跳转到第二个Activity再返回数据回来;

     第一个Activity:
     startActivityForResult方法接收两个参数,第一个是intent,第二个是请求码,用于之后的回调中判断数据的来源;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button test1_bt = findViewById(R.id.test1_bt);
        test1_bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivityForResult(intent, 1);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case 1:
                if (resultCode == RESULT_OK) {
                    if (data != null) {
                        Boolean flag = data.getBooleanExtra("extra_data", false);
                        Log.d("AAAAAAAAAAAA", " " + flag);
                    }
                }
                break;
            default:
        }
    }
}

     第二个Activity:
     设置数据并结束当前活动返回上一个活动;
     setResult接收两个参数,第一个参数用于向上一个活动返回处理结果,一般只使用RESULT_OK、RESULT_CANCELED,第二个参数把数据转过去; finish销毁当前活动。

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        Intent intent = new Intent();
        intent.putExtra("extra_data", true); // Boolean
        setResult(RESULT_OK, intent);
        finish();
    }
}

6)标记位 flag

Intent.FLAG_ACTIVITY_NEW_TASK

     如在一个应用中,当前栈为:ABC,在此基础上启动活动 B 的 intent设置为FLAG_ACTIVITY_NEW_TASK,栈就为:ABCB,和设置启动模式为 standard 一样的效果。

Intent.FLAG_ACTIVITY_CLEAR_TASK

     启动新的活动前,清除之前旧的活动。与Intent.FLAG_ACTIVITY_NEW_TASK一起使用才有效果!
     如一个应用中,当前栈为:AB,在此基础上启动新活动C 的intent设置为 FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK,跳转后,栈为:C,此时按下返回键,即可退出应用。

Intent intent = new Intent(SecondActivity.this, ThirdActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

Intent.FLAG_ACTIVITY_CLEAR_TOP

     当启动的活动,在栈中已经存在,清除在它之上的其它活动;
     如栈为:ABC,此时启动活动B,清除活动C,当前栈为:AB

Intent.FLAG_ACTIVITY_REORDER_TO_FRONT

     将启动的活动,放于栈顶;
     如栈为:ABC,启动活动B,此时栈就变为:ACB。

可以看下这个博文:活动启动模式

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值