启动Activity的几种方式 四大组件

Quibbler 2020-1-7 1892

启动Activity的几种方式


        启动Activity一般借助Intent,不仅可以启动本应用内的Activity,还可以启动第三方应用的Activity。启动还可以给Intent加上指定的flag,参考Activity启动的Flag



1、Intent显示启动

        一般启动本应用内的Activity可以使用这种方式,因为知道类名。显示启动也有多种方式,不过变来变去都一样。创建启动Activity用到的Intent最直接简洁的一种方式如下:

    Intent intent = new Intent(this, SettingsActivity.class);

        另一种方式:

    Intent intent = new Intent();
    intent.setClass(this,SettingsActivity.class);

        还有一种:

    Intent intent = new Intent();
    ComponentName componentName = new ComponentName(this, SettingsActivity.class);
    intent.setComponent(componentName);


        虽然显示Intent的创建方式这么多,但是查看源码不难发现最终都一样。借助内部的private ComponentName mComponent对象。

        第一张方式的源码,内部构造函数直接创建一个ComponentName对象:

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

        第二种创建一个空的Intent在setClass:

    public @NonNull Intent setClass(@NonNull Context packageContext, @NonNull Class<?> cls) {
        mComponent = new ComponentName(packageContext, cls);
        return this;
    }

        第三中方式更是多此一举,创建一个ComponentName对象,再赋值给Intent成员变量:

    public @NonNull Intent setComponent(@Nullable ComponentName component) {
        mComponent = component;
        return this;
    }



2、隐式Intent启动:Action

        一般用来启动第三方APP的Activity页面。隐式启动Activity需要在AndroidManifest.xml文件中对应Activity节点下配置要启动Activity的action和category。如果知道第三方APP特定Activity页面的action就可以启动它。

        AndroidManifest.xml中Activity节点下配置action和category,两个都需配置才有效。

    <activity
        android:name=".activity.ITheme"
        android:label="i主题">
        <intent-filter>
            <action android:name="com.vivo.action.theme.onlinepreview" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

        ①方式一:创建一个空的Intent,添加action和category。

    Intent intent = new Intent();
    intent.setAction("com.test.action");
    intent.addCategory("com.test.category");

        源码:

    public @NonNull Intent setAction(@Nullable String action) {
        mAction = action != null ? action.intern() : null;
        return this;
    }
    public @NonNull Intent addCategory(String category) {
        if (mCategories == null) {
            mCategories = new ArraySet<String>();
        }
        mCategories.add(category.intern());
        return this;
    }

        ②方式二:创建Intent的时候传入action。

    Intent intent = new Intent("com.test.action");

        源码:

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


        如果多个Activity具有相同的Action,那么通过Action隐式启动Activity,系统会先弹出应用选择对话框

    <activity
        android:name=".activity.ITheme"
        android:label="i主题">
        <intent-filter>
            <action android:name="com.vivo.action.theme.onlinepreview" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    
    <activity
        android:name=".activity.ITheme"
        android:label="i主题">
        <intent-filter>
            <action android:name="com.vivo.action.theme.onlinepreview" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>




3、ComponentName

        ComponentName:可以启动其他应用的Activity、Service。创建一个空的Intent,在创建一个ComponentName对象,设置给Intent对象即可。

    ComponentName    chatActivity =new ComponentName(param1,param2);
    //param1:Activity、Service所在应用的包名
    //param2:Activity、Service的包名+类名

        示例:

    ComponentName componentName = new ComponentName("com.vivo.reply","com.vivo.reply.activity.ITheme");
    intent.setComponent(componentName);
    startActivity(intent);

        注意第三方的Activity在Manifest.xml中应该将属性android:exported设置为true,对外暴露:

<activity android:name=".activity.ITheme
    android:exported="true"/>

        用这种方式启动需要注意如果目标APP没有安装,不存在指定的Activity会异常

E AndroidRuntime: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.reply/com.reply.activity.Theme}; have you declared this activity in your AndroidManifest.xml?
E AndroidRuntime:        at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2056)
E AndroidRuntime:        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1716)
E AndroidRuntime:        at android.app.Activity.startActivityForResult(Activity.java:5252)
E AndroidRuntime:        at d.k.a.c.startActivityForResult(:676)
E AndroidRuntime:        at android.app.Activity.startActivityForResult(Activity.java:5210)
E AndroidRuntime:        at d.k.a.c.startActivityForResult(:663)
E AndroidRuntime:        at android.app.Activity.startActivity(Activity.java:5581)



4、startActivity()

        最后调用Context中的startActivity(Intent intent)方法启动Activity。

        如果使用Activity的startActivity方法,不会有任何限制,因为Activity继承自Context,重载了startActivity方法。 

    startActivity(intent);

        Content中的startActivity方法,需要开启一个新的task。

    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    mContext.startActivity(intent);



不忘初心的阿甘
最新回复 (1)
    • 安卓笔记本
      3
        登录 注册 QQ
返回
仅供学习交流,切勿用于商业用途。如有错误欢迎指出:fluent0418@gmail.com