有些时候,我们需要为一个应用(apk)设置多个执行入口,也就是安装后,出现多个图标,各个icon是同一apk不同模块的入口,并且,各个模块运行在不同的进程中。例如系统的通讯录和通话记录就是同一个应用的不同入口。
android一个应用多个入口有以下三种实现方式:
1.在AndroidManifest文件中使用intent-filter。
<activity android:name=".MainActivity"
android:label="@string/RegisterSystemComponents"
android:icon="@mipmap/ic_launcher">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".LockScreen"
android:label="@string/OneKeyLock"
android:icon="@drawable/yy">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
2.在AndroidManifest文件中为不同的Activity设置属性process,使不同的Activity运行在不同的进程中。
Activity的process属性指定了Activity运行时所在的进程。
没有指定此属性时,所有程序组件都运行在应用程序默认的进程中,这个进程名跟应用程序的包名一致。
在AndroidManifest.xml文件中所有组件元素的process属性能够为该组件设定一个新的默认值。也就是说,任何组件的process属性都可以覆盖这个以包名命名的默认值,这样,就可以把apk放在多进程中运行。
设置权限的格式是android:process=”:process.xxx”,xxx可以自定义。
设置了自定义process后,这个activity运行时,apk会创建一个专属于这个组件或者说是activity的进程。
<application
android:allowBackup="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:label="@string/RegisterSystemComponents"
android:icon="@mipmap/ic_launcher"
android:process=":process.main"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".LockScreen"
android:label="@string/OneKeyLock"
android:icon="@drawable/yy"
android:process=":process.lock"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
需要注意的是为activity指定process属性后,还必须为其指定单例运行模式
即launchMode为singleInstance。
3.使用Activity的别名(activity-alias),同样也在Androidmanifest文件中进行配置。
activity-alias是android里为了重复使用Activity而设计的。
当在Activity的onCreate()方法里,执行getIntent().getComponent().getClassName();得到的可能不是这个Activity的名字,有可能是别名的名字。
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_nameB">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity-alias
android:name="LockScreen"
android:icon="@drawable/icon1"
android:screenOrientation="landscape"
android:targetActivity=".MainActivity">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
android:targetActivity=”.MainActivity”这句在别名设置中,设置目标activity。
android:exported=”true”说明允许别的app调用该activity。
此时,apk会创建两个进入点,getIntent().getComponent().getClassName()得到的名字就不一样,一个是.MainActivity,一个是.LockScreen。
总结:上面三种实现方式其实原理都是一样的,都是为第二个Activity添加”intent-filter为程序增加入口图标。
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>