Android入门(5):Intent的使用

上一篇:Android入门(4):Toast、Menu使用及活动的销毁

Intent是什么

各个活动通过Intent可以紧密的联系起来,Intent是Android程序中个组件进行交互的一种重要方式,不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可被用于启动活动、启动服务以及发送广播等场景。

​ Intent大致可以分为显式Intent和隐式Intent

创建第二个活动

我们再新建一个活动,这次我们勾选Generate Layout File
在这里插入图片描述
我们修改一下布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/button_2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button 2"
        />
</LinearLayout>

as生成的SecondActivity代码暂时可以不用修改,同时as还为我们在AndroidManifest.xml文件注册了该活动。

显式Intent

Intent有多个构造函数的重载,其中一个是Intent(Context packageContext, Class<?> cls). 这个构造函数接受两个参数,第一个参数Context要求提供一个启动活动的上下文,第二个参数Class则是指定想要启动的目标活动,通过这个构造函数就可以构建出Intent的“意图”。然后我们应该怎么使用这个Intent呢?Activity类中提供了一个startActivity()方法,这个方法是专门用于启动活动的,它接收一个Intent参数,这里我们将构建好的Intent传入startActivity()方法就可以启动目标活动了。

修改button1的功能

@Override
public void onClick(View v) {
    Intent intent = new Intent(FirstActivity.this,
                               SecondActivity.class);
    startActivity(intent);
}

当点击button1就启动了SecondActivity,如果想返回上一个活动,只需back即可销毁当前活动。使用这种方式来启动活动,Intent的“意图”非常明显,因此我们称之为显式Intent。

隐式Intent

隐式Intent并不明确指出我们想要启动哪个活动,而是指定了一些列更为抽象的action和category等信息,然后由系统去分析这个Intent,并帮我们找出合适的活动去启动。

​ 什么是合适的活动呢?简单来说就是可以相应这个隐式Intent的活动,那么目前SecondActivity可以响应什么样的隐式Intent呢?暂时,好像什么都响应不了。

​ 通过在activity标签下配置intent-filter的内容,可以指定当前活动能够响应的action和category,打开AndroidManifest,添加如下代码:

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

只有当action和category中的内容同时匹配,这个SecondActivity才能响应Intent,注意这里category使用一种默认的category,在调用startActivity方法时会自动将这个category添加到Intent中。

 @Override
public void onClick(View v) {
    Intent intent = new Intent("com.example.activitytest.ACTION_START");
    startActivity(intent);
}

我们通过上述代码进行调用。

​ 每个Intent中只能指定一个action,但却能指定多个category。我们尝试添加一个category:在AndroidManifest中添加<category android:name="com.example.activitytest.MY_CATEGORY"></category>→在上述代码3行后添加intent.addCategory("com.example.activitytest.MY_CATEGORY");即可

example

尝试使用隐式Intent打开百度

@Override
public void onClick(View v) {
    Intent intent = new Intent(Intent.ACTION_VIEW); 
    intent.setData(Uri.parse("http://www.baidu.com"));
    startActivity(intent);
}

Intent.ACTION_VIEW,这是一个Android系统内置的动作,setData方法接受一个Uri对象,主要用于指定当前Intent正在操作的数据,而这些数据通常都是以字符串的形式传入Uri.parse()方法中解析产生的。

与此对应,我们还可以在intent-filter标签中配置一个data标签:

  • android:scheme。用于指定数据的协议部分,如http
  • android:host。
  • android:port。
  • android:path。路由
  • android:mimeType。用于指定可以处理的数据类型,允许使用通配符的方式进行指定。

注意:只用data标签中指定的内容与Intent中携带的Data完全一致时,当前活动才能够响应,但当data标签只是指定了http,则可以响应所有的http协议的Intent。

我们再次新建一个活动ThirdActivity,在AndroidManifest中写入:
在这里插入图片描述
注意爆红是因为逻辑上没有检测是否安装Chrome,所以这里我们使用安装了的模拟器运行运行结果如图所示:
在这里插入图片描述
这里选择我们要打开的应用。

除了http协议外,我们还可以指定很多其它协议,比如geo表示显示地理位置、tel表示拨打电话

@Override
public void onClick(View v) {
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setData(Uri.parse("tel:10086"));
    startActivity(intent);
}

活动之间数据的传输

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

​ 在启动活动时传递数据的思路很简单,Intent中提供了一系列putExtra()方法的重载,可以把我们想要传递的数据暂存在Intent中,启动了另一个活动后,只需把这些数据再从Intent中取出就可以了。类似于键值对的形式

在FirstActivity中存入data

@Override
public void onClick(View v) {
    String data = "Hello SecondActivity";
    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
    intent.putExtra("extra_data", data);
    startActivity(intent);
}

在SecondActivity取出data

public class SecondActivity extends AppCompatActivity {
    private static final String TAG = "SecondActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_layout);
        Intent intent = getIntent();
        String data = intent.getStringExtra("extra_data");
        Log.d(TAG, "onCreate: "+data);
    }
}

在这里插入图片描述

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

​ 返回貌似是没有Intent来启动活动。其实,Activity中还有一个startActivityForResult()方法也是用于启动活动的,但这个方法期望在活动销毁的时候能够返回一个结果给上一个活动。

​ startActivityForResult方法接受两个参数,第一个参数还是Intent,第二参数是请求码,用于在之后的回调中判断数据的来源。

在FirstActivity中使用startActivityForResult启动第二个活动:

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

因为待会有一个函数在第一个活动中接受所有返回的数据,所以需要一个requestCode来判断是哪个活动发送来的,这里1标识着第二个活动

在第二个活动设定返回数据:

Button button2 = (Button) findViewById(R.id.button_2);
button2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent();
        intent.putExtra("data_return", "Hello FirstActivity");
        setResult(RESULT_OK, intent);
        finish();
    }
});

通过setResult方法设定返回数据,第一个参数为resultCode,一般为RESULT_OK或RESULT_CANCELED,用于对返回结果的处理。

在第一个活动中重写onActivityResult方法来接受和处理返回的数据:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    switch (requestCode) {
        case 1:
            if(resultCode == RESULT_OK) {
                String res = data.getStringExtra("data_return");
                Log.d(TAG, "onActivityResult: "+res);
            }
            break;
        default:
    }
}

点击button1→点击button2,打印出:
在这里插入图片描述
若是通过back返回的话我们只需重写onBackPressed()方法即可

@Override
public void onBackPressed() {
    Intent intent = new Intent();
    intent.putExtra("data_return", "Hello FirstActivity");
    setResult(RESULT_OK, intent);
    finish();
}

下一篇:Android入门(6):活动的生命周期

发布了86 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42317011/article/details/104328806
今日推荐