启动Activity的几种方式

QuibblerQuibbler 2020-01-07 约 12 分钟 2520 次阅读

启动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);

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w