• (转载)Android理解:显式和隐式Intent


    Intent分两种:显式(Explicit intent)和隐式(Implicit intent)

    一、显式(设置Component)

    显式,即直接指定需要打开的activity对应的类。 以下多种方式都是一样的,实际上都是设置Component直接指定Activity类的显式Intent,由MainActivity跳转到SecondActivity:

    1、构造方法传入Component,最常用的方式

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


    2、setComponent方法

    ComponentName componentName = new ComponentName(this, SecondActivity.class);  
    // 或者ComponentName componentName = new ComponentName(this, "com.example.app016.SecondActivity");  
    // 或者ComponentName componentName = new ComponentName(this.getPackageName(), "com.example.app016.SecondActivity");  
      
    Intent intent = new Intent();  
    intent.setComponent(componentName);  
    startActivity(intent); 


    3、setClass/setClassName方法

    Intent intent = new Intent();  
      
    intent.setClass(this, SecondActivity.class);  
    // 或者intent.setClassName(this, "com.example.app016.SecondActivity");  
    // 或者intent.setClassName(this.getPackageName(), "com.example.app016.SecondActivity");  
              
    startActivity(intent);  

    显式Intent通过Component可以直接设置需要调用的Activity类,可以唯一确定一个Activity,意图特别明确,所以是显式的。设置这个类的方式可以是Class对象(如SecondActivity.class),

    也可以是包名加类名的字符串(如"com.example.app016.SecondActivity")。这个很好理解,在应用程序内部跳转界面常用这种方式。

    二、隐式

    隐式,即不是像显式的那样直接指定需要调用的Activity,隐式不明确指定启动哪个Activity,而是设置Action、Data、Category,让系统来筛选出合适的Activity。

    筛选是根据所有的<intent-filter>来筛选。

    下面以Action为例:

    AndroidManifest.xml文件中,首先被调用的Activity要有一个带有<intent-filter>并且包含<action>的Activity,设定它能处理的Intent,并且category设为"android.intent.category.DEFAULT"。

    action的name是一个字符串,可以自定义,例如我在这里设成"abcdefg":

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


    然后,在MainActivity,才可以通过这个action name找到上面的Activity。

    下面两种方式分别通过setAction和构造方法方法设置Action,两种方式效果相同。

    1、setAction方法

    Intent intent = new Intent();  
    intent.setAction("abcdefg");  
    startActivity(intent);  


    2、构造方法直接设置Action

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


    通过设置Action字符串,表明自己的意图,即我想干嘛,需要由系统解析,找到能够处理这个Intent的Activity并启动。

    比如我想打电话,则可以设置Action为"android.intent.action.DIAL"字符串,表示打电话的意图,系统会找到能处理这个意图的Activity,例如调出拨号面板。

    有几点需要注意:

    1、 这个Activity其他应用程序也可以调用,只要使用这个Action字符串。这样应用程序之间交互就很容易了,例如手机QQ可以调用QQ空间,可以调用腾讯微博等。

    因为如此,为了防止应用程序之间互相影响,一般命名方式是包名+Action名,例如这里命名"abcdefg"就很不合理了,就应该改成"com.example.app016.MyTest"。

    2、 当然,你可以在自己的程序中调用其他程序的Action。 例如可以在自己的应用程序中调用拨号面板:

    Intent intent = new Intent(Intent.ACTION_DIAL);  
    // 或者Intent intent = new Intent("android.intent.action.DIAL");  
    // Intent.ACTION_DIAL是内置常量,值为"android.intent.action.DIAL"  
    startActivity(intent);  

    3、一个Activity可以处理多种Action 只要你的应用程序够牛逼,一个Activity可以看网页,打电话,发短信,发邮件。。。当然可以。 Intent的Action只要是其中之一,就可以打开这个Activity。

    activity  
        android:name="com.example.app016.SecondActivity">  
        <intent-filter>  
            <!-- 可以处理下面三种Intent -->  
            <action android:name="com.example.app016.SEND_EMAIL"/>  
            <action android:name="com.example.app016.SEND_MESSAGE"/>  
            <action android:name="com.example.app016.DAIL"/>  
            <category android:name="android.intent.category.DEFAULT" />  
        </intent-filter>  
    </activity>  


    对于一个Action字符串,系统有可能会找到一个Activity能处理这个Action,也有可能找到多个Activity,也可能一个都找不到。
    1、找到一个Activity
    很简单,直接打开这个Activity。这个不需要解释。
    2、找到多个Acyivity
    系统会提示从多个activity中选择一个打开。
    例如我们自己开发一个拨号面板应用程序,可以设置activity的<intent-filter>中Action name为"android.intent.action.DIAL",这样别的程序调用拨号器时,

    用户可以从Android自带的拨号器和我们自己开发的拨号器中选择。

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


    这也就是当Android手机装上UC浏览器后,打开网页时会弹出选择Android自带浏览器还是UC浏览器,可能都会遇到过。
    3、一个Activity都没找到
    一个都没找到的话,程序就会出错,会抛出ActivityNotFoundException。比如随便写一个action字符串:

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


    所以应该注意try catch异常。

    Intent intent = new Intent("asasasas");  
    try  
    {  
        startActivity(intent);  
    }  
    catch(ActivityNotFoundException e)  
    {  
        Toast.makeText(this, "找不到对应的Activity", Toast.LENGTH_SHORT).show();  
    }  


    或者也可以使用Intent的resolveActivity方法判断这个Intent是否能找到合适的Activity,如果没有,则不再startActivity,或者可以直接禁用用户操作的控件。

    Intent intent = new Intent(Intent.ACTION_DIAL);  
    if(intent.resolveActivity(getPackageManager()) == null)  
    {  
        // 设置控件不可用  
    }  


    注意resolveActivity方法返回值就是显式Intent上面讲到的ComponentName对象,一般情况下也就是系统找到的那个Activity。

    但是如果有多个Activity可供选择的话,则返回的Component是com.android.internal.app.ResolverActivity,也就是用户选择Activity的那个界面对应的Activity,这里不再深究。

    Intent intent = new Intent(Intent.ACTION_DIAL);  
    ComponentName componentName = intent.resolveActivity(getPackageManager());  
    if(componentName != null)  
    {  
        String className = componentName.getClassName();  
        Toast.makeText(this, className, Toast.LENGTH_SHORT).show();  
    }  
  • 相关阅读:
    二分+RMQ/双端队列/尺取法 HDOJ 5289 Assignment
    思维题 HDOJ 5288 OO’s Sequence
    树形DP Codeforces Round #135 (Div. 2) D. Choosing Capital for Treeland
    最大流增广路(KM算法) HDOJ 1853 Cyclic Tour
    最大流增广路(KM算法) HDOJ 1533 Going Home
    最大流增广路(KM算法) HDOJ 2255 奔小康赚大钱
    Complete the Word CodeForces
    Gadgets for dollars and pounds CodeForces
    Vasya and Basketball CodeForces
    Carries SCU
  • 原文地址:https://www.cnblogs.com/liaojie970/p/5827433.html
Copyright © 2020-2023  润新知