Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

Activity(Intent-filter详解及跳转)

$
0
0

转载请注明出处:http://blog.csdn.net/huiblog/article/details/53221809

五壮士之 Activity

  • 开场白

    为什么说是五壮士呢?
    Android知识体系中最重要的就是四大组件,也就是ActivityServiceContentProvider以及BrocastRecever。还有一个重要的组件Application。所以,四大组价+Application=五壮士。
    这重要的五个家伙就跟人体的心、肝、脾、肺、肾一样,个个组件之间分工明确,构成了我们强大的Android体系。这里我们简单的了解一下就可以了,后续文章我们会一一聊聊的。
    这是Activity系列文章第一节。

什么是Activity

  • 概论

    Activity就像人的脸面一样,这个玩意承载着一个APP的单独的一个门面。通过这个组件,我们可以让APP当前的页面中显示任何我们想要显示的东西。例如:我们看到的文字(可能是Textview这个控件)、一个按钮(可能是Button 这个控件)、
    一张图片(可能是ImageView 这个控件)。

    为什么说可能呢?因为Android的控件是很灵活的,所看到的的不一定是真的,你看到的是按钮(Button),可能他是使用图片+文字组合在一起的。(当然,后续文章中我们会知道,Button的实质就是图片+文字组合在一起的)

  • UI构成简介

    其实Activity并不是在对象里面添加了一个部局文件那样简单。
    我们所用的布局文件其实是通过PhoneWindow放到了DecorView的mContentParent里面,最终形成了我们看到的。

    • 简单图示

    Activity UI简单图示
    这里就放个图在这,简单看看就行。Activity的后续文章中我会进行详解的。

Activity的跳转

我们新建一个Activity后,需要在AndroidManifest.xml这个重要的文件中进行注册我们的Activity,为什么要在这个文件中注册呢?因为这个文件相当于一个APP的简历,通过这个简历我们可以知道这个APP想要什么权限、有哪些需要展示的页面、能接受什么广播、有哪些服务、能向外界提供哪些数据,等等。
使用Android Studio 创建一个默认的APP,我们看看这个AndroidManifest.xml里都写了什么。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.asia.testactivity">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity> 
    </application>
</manifest>

捡当前我们讲的跳转来看,<activity android:name=".MainActivity">这个表示MainActivity是一个Activity。而<intent-filter> 是意图过滤器在他的子节点的两行代码<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
表示当前所在的父节点的Activity是主Activity,也就是说打开APP时,系统会默认打开这个Activity也就是这段XML中的MainActivity。具体intent-filter是干嘛的后面会讲的。

Activity的跳转呢有两种跳转方法,分别是显示跳转隐式跳转

  • 显示跳转
    显示跳转就是说很明显我们知道要跳转到哪一个Activity的意思。
    Demo:
Intent intent = new Intent();
intent.setClass(context, TargetActivity.class);
startActivity(intent);

执行上面的一段代码后,我们就能跳转到到指定的TargetActivity了。
另一种写法:

Intent intent =  new Intent(context, TargetActivity.class);
startActivity(intent);

两种意思都一样,指定了目的Activity,使用Intent跳转。

  • 隐式跳转

隐式跳转就像一种模糊跳转,就跟上网买衣服差不多,过滤条件写着冬季、蓝色、175cm的大衣,电商就列了一列衣服供你选择。隐士跳转呢,我们指定要跳转的Activity需要什么样的条件,系统会将系统中所有的应用的AndroidManifest.xml遍历一遍找到你提出条件的Activity,然后跳转到这个Activity中。如果有多个符合条件的Activity,就弹窗问你需要跳转到哪一个,如果没有找到符合条件的Activity,系统就会骂你,傻啊你,没有你这么苛刻条件的Activity,然后就抛异常了。O(∩_∩)O哈哈~

Demo主要代码
MainActivity

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("hui", "MainActivity onCreate");
    }

    public void onClick(View view){
        Intent intent = new Intent();
        intent.setAction("my.custom.action");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.setData(Uri.parse("mydata:lalalala"));
        startActivity(intent);
    }

}

AndroidManifest.xml中SecondActivity的注册代码

 <activity android:name=".SecondActivity">
            <intent-filter>
                <action android:name="my.custom.action" />
                <data android:scheme="mydata"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
</activity>

效果:
代码结果

上面的例子看一下,下面就详细讲解一下这个intent-filter强大的过滤功能,最后在看这个例子就明白了。

intent-filter (意图过滤器)

有三个重要的参数,action、category、data。

  • action 可以翻译为功能,这个东西呢谷歌提供的是给系统用的,我们开发APP时由我们开发人员自定义的,代表着我们自己定义的这个Activity拥有什么样的功能。
  • category 类别,上面写的”android.intent.category.DEFAULT”就是一般情况下用的默认类别。
    category是使用系统给我们提供的,有很多种,例如:
    category举例
    不同的category代表着Activity的不同类别,比如第一个“”android.intent.category.BROWSABLE”代表着这是浏览器类别的。
    其他的常用action及category参考这个
  • data 这个东西的官方意思是“表示操作数据的URI和MIME类型”,也就是说包含了当前action所必须的数据规范。举例来说:我们调用系统的打电话的功能(setAction(Intent.ACTION_CALL))就必须要传递过去一个电话号码(setData(Uri.parse(“tel:110”))),上面两个设置后就可以给110打电话了(当然需要权限)。如果没有电话号码调用打电话的功能没意义的。 data有两个属性:

    • 属性一:scheme
      上例子中,<data android:scheme="mydata"/>,那么如果你想打开我这个Activity就必须给我一个以mydata为前缀开头的数据,例如上面的intent.setData(Uri.parse(“mydata:lalalala”));我们获取到这个数据就可以做我们自己的操作。

      对于Intent#setData方法,public Intent setData(Uri data) 需要一个 uri,我们通过 public static Uri parse(String uriString) 就可以将“mydata:lalalala”传递给目的Activity了。
      如果有多个scheme,例如有两个scheme约束:<data android:scheme="mydata"/><data android:scheme="otherdata"/> 我们的setData方法只需要匹配其中任意一个即可,使用intent.setData(Uri.parse("mydata:xxxxx")) 或者 intent.setData(Uri.parse("otherdata:xxxx")):其中任意一个都可以与这个intent-filter匹配

    • 属性二:mimeType
      这个东西代表了传递的数据类型,比如mp4类型(audio/mpeg),3gp类型(audio/3gpp),等等。注意:格式必须是XXX/XXX类似的。使用public Intent setType(String type) 就可以了。

      注意!
      在同时有setData和setType时,这个东西互斥的,不能同时生效。必须只能使用public Intent setDataAndType(Uri data, String mimeType) 。不知道谷歌当初怎么想的^(* ̄(oo) ̄)^。

现在看上面隐士跳转的demo代码是不是明白了许多,↖(^ω^)↗。
在SecondActivity的注册代码中,intent-filter的子节点action和category代表着这个Activity是 “android.intent.category.DEFAULT”类型的Activity,拥有”my.custom.action”功能的Activity,同时需要mydata前缀的数据。
而在MainActivity 的隐式跳转中,系统根据指定的action和category以及data的scheme遍历全部应用AndroidManifest.xml文件,发现与SecondActivity的约束条件一致,完全匹配,而且只有这一个,就打开了SecondActivity。

完全匹配的指的是,我如果要求身高175、体重50kg以上这条件,那么相亲对象就必须符合这两个条件。在代码中,意思是你必须符合我Intent-filter中的所有约束条件,才是匹配我的资格。还拿上面SecondActivity例子说明,SecondActivity的intent-filter中有action、category和data三个约束,那么你给我的intent中必须也有三个对应的约束,才能匹配。如果我的intent中只有action和category这两个约束值,那么两者是不匹配的,完全一致才匹配。

Activity跳转流程

借用Google的图示,加深理解。
Intent跳转
无论隐式跳转还是显示跳转,流程都如上图所示,Activity A创建一个包含要跳转到目的Activity信息的Intent,然后通过startActivity将intent数据发给系统,[2]系统拿到intent后进行解析intent中数据,查询手机中所有的APP中的AndroidManifest.xml文件中的intent-filter,找与之匹配的intent-filter,【3】当找到了与之匹配的intent-filter后就打开这个Activity。找不到,就抛异常(^o^)/~

最后,看下如果有多个符合约束条件的Activity会怎么样呢?
新建第三个Activity,注册的intent-filter如下:

<activity android:name=".ThridActivity">
            <intent-filter>
                <action android:name="my.custom.action" />
                <data android:scheme="mydata"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

多个完全匹配的Activity中Intent-filter

全部代码:http://download.csdn.net/detail/huiblog/9686973

作者:huiblog 发表于2016/11/18 19:30:28 原文链接
阅读:11 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>