转载请注明出处
http://blog.youkuaiyun.com/hansion3333/article/details/54946304
本文出自Hansion的博客
目录
前言
每当双11时,手机中的“天猫”的图标就会变成双11主题的图标。这是怎么实现的呢?
有人说是更新App,没错,可以实现。但是有些大材小用了,毕竟更新一个版本。
个人猜测是在双11前的某次更新版本时已将节日图片资源打包入内,根据服务器提供的数据动态改变。所以就有了本文
需要用到的知识:activity-alias
alias 英 [ˈeɪliəs] 美 [ˈeliəs, ˈeljəs]
n. 别名,化名;顾名思义,activity-alias并不是代表一个Activity,而是代表一个已经存在的Activity的别名。
它使用在清单文件中,类似Activity标签。它可用来设置某个Activity的快捷入口
activity-alias基本用法
<activity-alias android:enabled=["true" | "false"]
android:exported=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
android:name="string"
android:permission="string"
android:targetActivity="string" >
...
</activity-alias>
属性解释:
属性 | 含义 |
---|---|
enabled | 是否生效。配置多个activity-alias时,如果只想一个生效,就设置一个为true |
exported | 是否可以被其他应用调起,配置intent-filter时默认为true,未配置intent-filter时默认为false,只能被应用自身调起 |
icon | 自定义生效时的icon |
label | 作用同Activity标签中的label属性,主要表现为桌面上的app名称和activity的title的名称 |
name | 该activity-alias的名字 |
permission | 指明通过别名声明调起目标Activity所必需的权限 |
targetActivity | 指明目标Activity,类似于Activity标签中的name属性,需写明包类路径。表明通过activity-alias调起的是哪个Activity |
代码范例:
- AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="Android ICON"
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>
<activity-alias
android:name=".MainAliasActivity"
android:targetActivity=".MainActivity"
android:label="UNIQLO ICON"
android:icon="@mipmap/ic_launcher_change"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
</application>
这里声明了一个activity-alias,目标Activity为MainActivity,label为“UNIQLO ICON”,指定了一个与原icon不同的icon,目前未启用
我们在MainActivity中增加两个按钮,用于切换icon
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<Button
android:layout_margin="10dp"
android:id="@+id/mChangeToAndroid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="安卓安卓" />
<Button
android:layout_margin="10dp"
android:id="@+id/mChangeToUniQlo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="一库一库" />
</LinearLayout>
在MainActivity中对按钮的点击事件进行处理,并进行相应的切换操作
- MainActivity.class
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
Button mChangeToAndroid = (Button) findViewById(R.id.mChangeToAndroid);
Button mChangeToUniQlo = (Button) findViewById(R.id.mChangeToUniQlo);
mChangeToAndroid.setOnClickListener(this);
mChangeToUniQlo.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.mChangeToAndroid:
changeIcon("com.hansion.changelaunchericon.MainActivity");
break;
case R.id.mChangeToUniQlo:
changeIcon("com.hansion.changelaunchericon.MainAliasActivity");
break;
default:
break;
}
}
public void changeIcon(String activityPath) {
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(getComponentName(),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(new ComponentName(this, activityPath),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
//重启桌面 加速显示
// restartSystemLauncher(pm);
}
public void restartSystemLauncher(PackageManager pm) {
ActivityManager am = (ActivityManager) getSystemService(Activity.ACTIVITY_SERVICE);
Intent i = new Intent(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
i.addCategory(Intent.CATEGORY_DEFAULT);
List<ResolveInfo> resolves = pm.queryIntentActivities(i, 0);
for (ResolveInfo res : resolves) {
if (res.activityInfo != null) {
am.killBackgroundProcesses(res.activityInfo.packageName);
}
}
}
}
- 通过以上代码切换icon后,需在桌面等待数秒钟后生效。如下图:
- 如果需要加速生效,则需要在更改icon后重启一下系统桌面。解开第34行代码的注释,增加权限
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
如下图:
需要注意的是,更换icon会关闭App,所以切换icon要选择一个合适的时机来进行操作。
个人认为本文中切换APP启动方式一定不是最好的方式,图片资源从服务器动态获取才更灵活。如果你有更好的实现方式,请留言给我,谢谢。