认识Intent

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

Intent的用法分为显式Intent和隐式Intent两种。接下来详细解析。

1.了解Intent的构造方法

Intent的方法有很多,通过认识构造方法,我们能够窥探到Intent的不同用法。

1.空构造方法:

    public Intent() {
    }

2.根据另一个Intent创建的构造方法

    public Intent(Intent o) {
        this.mAction = o.mAction;
        this.mData = o.mData;
        this.mType = o.mType;
        this.mPackage = o.mPackage;
        this.mComponent = o.mComponent;
        this.mFlags = o.mFlags;
        this.mContentUserHint = o.mContentUserHint;
        if (o.mCategories != null) {
            this.mCategories = new ArraySet(o.mCategories);
        }
        if (o.mExtras != null) {
            this.mExtras = new Bundle(o.mExtras);
        }
        if (o.mSourceBounds != null) {
            this.mSourceBounds = new Rect(o.mSourceBounds);
        }
        if (o.mSelector != null) {
            this.mSelector = new Intent(o.mSelector);
        }
        if (o.mClipData != null) {
            this.mClipData = new ClipData(o.mClipData);
        }
    }

3.由一条Action创建的构造方法

    public Intent(String action) {
        setAction(action);
    }

其中的setAction()方法如下:

    public Intent setAction(String action) {
        mAction = action != null ? action.intern() : null;
        return this;
    }

4.通过Action和Uri共同创建的构造方法

    public Intent(String action, Uri uri) {
        setAction(action);
        mData = uri;
    }

5.通过Context和Class文件创建的构造方法

    public Intent(Context packageContext, Class cls) {
        mComponent = new ComponentName(packageContext, cls);
    }

6.大杂烩,通过Action、Uri、Context还有Class文件创建的构造方法

    public Intent(String action, Uri uri,
            Context packageContext, Class cls) {
        setAction(action);
        mData = uri;
        mComponent = new ComponentName(packageContext, cls);
    }

通过这些构造方法,我们需要从中学习到,不同构造方法的Intent,其作用是不同的。

1.参数要求为Context以及Class的

接下来会在构造方法中会创建出ComponentName对象,这个是Android的组件,是可以具体到某个具体的组件的,这种就是显式的使用方法。

2.参数要求为Action的

接下来会在构造方法中调用setAction()方法,也就是给mAction赋值,对应到AndroidManifest文件中的标签,在启动时,如果配置了相同action和category的Activity都可能被启动起来,如果匹配到多个,会弹出对话框让用户手动选,这种就是隐式的使用方法。

2.隐式使用Intent的注意事项

  • 每个Intent中只能指定一个action,但是可以指定多个category。

  • startActivity()方法中会自动将"android.intent.category.DEFAULT"这个默认的category添加到Intent中,如果被启动的Activity声明的category正好就是默认的话,可以不用写。

  • 在AndroidManifest文件中声明Activity的时候,如果希望这个Activity是用隐式的方式被启动,那么在标签中,必须要添加上这一条:

如果AndroidManifest文件中没有这一条,那么即使Action能够匹配上依然会崩溃。
如下:

           
               

               
           

代码调用:

                Intent intent = new Intent();
                intent.setAction("com.company.windmajor.JUMP");
                startActivity(intent);
  • 如果有自己限定category的需求,那么可以先添加上面一点中提到的DEFAULT的category,然后再定义自己的category。然后在java代码中添加自己定义的category。如下:
            
                

                
                
            

代码中的调用:

                Intent intent = new Intent();
                intent.setAction("com.company.windmajor.JUMP");
                intent.addCategory("com.company.windmajor.category.JUMP");
                startActivity(intent);

3.更多隐式Intent的用法

使用Intent,还可以启动其他App的Activity,这将使得Android多个应用程序之间的功能共享成为了可能。
这里介绍几个用法:Intent.ACTION_VIEW和Intent.ACTION_DIAL

(1)Intent.ACTION_VIEW

这个Action是系统定义的Action,可以将带有浏览器功能的App给打开,使用代码如下:

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

这段代码的效果就是打开浏览器,然后访问百度网。
setData()的方法接受Uri对象,主要用于指定当前Intent正在操作的数据,而这些数据通常都是以字符串的形式传入到Uri.parse()方法中解析产生的。
与此对应,我们还可以在标签中再配置一个标签,用于更精确的指定当前活动能够相应什么类型的数据。标签中,主要可以配置以下内容。

  • android:scheme 指定数据的协议部分,如上面代码里的http部分
  • android:host 指定数据的主机名部分,如上面代码里的www.baidu.com部分
  • android:port 指定数据的端口部分,一般紧随在主机名之后
  • android:path 指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容
  • android:mimeType 指定可以处理的数据类型,允许使用通配符的方式进行指定。

只有标签中指定的内容和Intent中携带的Data完全一致是,当前Activity才能响应该Intent。

那么如何自己创建一个可以响应系统需求的Activity呢?
首先创建一个布局文件:




    



然后创建一个新的Activity:

public class TwoActivity extends AppCompatActivity {

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

    }
}

最后非常重要的是一定要在AndroidManifest文件中注册新的Activity

        
            
                
                
                
            
        

这样运行起来之后,点击刚才的那个按钮,就可以看到选择启动程序的一个列表,列表中包括浏览器还包括我们刚刚创建新Activity的这个程序。当然只有打开浏览器,我们才能看到百度网页面的各种广告,点击我们自己的程序是不能看到的,因为我们的程序也没有写处理浏览登陆的代码。

(1).Intent.ACTION_DIAL

使用代码如下:

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

4.Activity之间的数据互传

Intent可以用来启动Activity,当然也是可以传递数据的,为了方便Activity之间的数据通信,Activity提供了putExtra()方法的重载,可以传递许多中类型的数据。
使用代码如下:

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, TwoActivity.class);
                intent.putExtra("EXTRA_DATA","Hello SecondActivity");
                startActivity(intent);
            }
        });

这里putExtra()方法的第一个参数是“键”,第二个参数是真正的“值”,键通常都是String类型的,值可以有很多种类型。那么这个地方传递了,别的地方如何取呢?

        Intent intent = getIntent();
        String data = intent.getStringExtra("EXTRA_DATA");

只需要在被启动的Activity里面使用如上的代码即可。当然要知道传的时候是什么类型,取的时候必须要能类型匹配上。不然不行。

当上一个Activity传递数据给下一个Activity,那么下一个Activity如何将数据结果传递回给上一个Activity呢?这里需要介绍一下startActivityForResult()方法。
这个方法需要两个参数,第一个参数是启动Intent,第二个参数是启动的请求码,只要是唯一的整型数字即可。

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, TwoActivity.class);
                intent.putExtra("EXTRA_DATA", "Hello SecondActivity");
                startActivityForResult(intent, 1);
            }
        });

当用户在界面TwoActivity完成了相应的操作,得到了想要的数据,需要将这个数据返回给第一个MainActivity,只需要下面这么做:

        twoButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.putExtra("EXTRA_RETURN", "This is the result...");
                setResult(RESULT_OK, intent);
                finish();
            }
        });

我们看到上面的Intent仅仅只是用来传递数据,setResult()方法很重要,第一个参数用于向前一个Activity返回处理结果,一般只使用RESULT_OK或RESULT_CANCELED这两个系统定义好的值表示成功与失败,第二个参数是把带有数据结果的Intent对象传递回去。最后使用finish()方法将当前的Activity销毁。

由于我们是使用startActivityForResult()方法来启动的第二个Activity,这种启动方法需要实现一个特殊的方法才可以使用第二个Activity返还回来的数据。

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
            case 1:
                if (resultCode == RESULT_OK) {
                    String returnedData = data.getStringExtra("EXTRA_RETURN");
                    Log.i("MainActivity", returnedData);
                }
                break;
            default:
                break;
        }
    }

这个方法有三个参数,第一个参数requestCode是启动第二个Activity时的启动码,我们设置的是1,第二个参数resultCode是从第二个Activity返还回来时的结果码,一般有两种RESULT_OK和RESULT_CANCELED,第三个参数data就是带着数据的Intent对象。

以上就是Intent的一些简单的特性和使用方法,希望共同勉励。

案例和知识点都来源于郭霖的《第一个行代码》,在此特别感谢郭老师,希望大家看完本篇文章后,希望全面了解的可以购买郭老师的书。

你可能感兴趣的:(认识Intent)