上一篇讲到gradle批量打包Android apk:不同的包使用不同的icon、label,经过一段时间的研究发现,通过配置manifest,使用gradle可以批量打包不不同功能的apk。
我们先实现一个简单的功能:apk1保持不变,给apk2替换一个launcher Activity,apk1和apk2对应的manifest分别是AndroidManifest1.xml、AndroidManifest2.xml,依照上面几篇文章操作下来,我们已经搭好了环境,直接进入我们今天的话题。具体步骤如下(这篇文章以上几篇为基础,如果有觉得很突兀不理解的地方,请参考上面几篇文章):
一、给Android工程增加一个新的activity类
新增的activity类命名为TestActivity,简单的初始化就可以了,实例代码如下:
public class TestActivity extends Activity{
private String TAG = "TestActivity";
private FrameLayout myLayout = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate , packageName = " + this.getPackageName());
myLayout = new FrameLayout(this.getApplicationContext());
LayoutParams mLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
myLayout.setLayoutParams(mLayoutParams);
myLayout.setBackgroundColor(Color.BLUE);
this.setContentView(myLayout);
}
@Override
public void onStart()
{
super.onStart();
Log.d(TAG, "onStart");
}
二、配置AndroidManifest2.xml
将TestActivity配置到AndroidManifest2.xml中,置为launcher activity,并删除之前的launcher activity,代码实例如下:
<application
android:allowBackup="true"
android:label="@string/palette"
android:icon="@drawable/ic_launcher2"
tools:replace="android:label,android:icon,android:theme"
android:theme="@android:style/Theme.Wallpaper" >
<activity
android:name="com.example.erase.TestActivity"
android:label="@string/palette" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
三、配置公共AndroidManifest.xml
根据manifest merger原理,编译出来的apk的manifest清单是公共AndroidManifest.xml和AndroidManifest2.xml的合集,所以要删除公共AndroidManifest.xml中的launcher activity,否则会导致一个应用有两个不同launcher activity,安装后的现象是:Android设备的全部应用里会一次性增加两个图标,但是名称不相同,卸载的时候发现他们属于同一个应用。修改之后的AndroidManifest.xml是下面这样的:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.erase"
android:versionCode="100002"
android:versionName="1.00.002" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
</application>
</manifest>
所以apk之间有差别的组件一定在各自的AndroidManifest*.xml配置,公共部分才可以在AndroidManifest.xml中配置,避免打包的时候混入不需要的代码。
四、编译、安装验证
在cmd中执行gradle clean 、gradle build,编译成功后,安装apk,会发现apk1和apk2的launcher界面的确不一样。
本人这次只是试了一下替换activity,service、Receiver和contentProvider还没有试,道理应该都一样,大家可以自己测试一下。大家可以搜“test gradle on eclipse”找源代码。
另外,也可以在同一套代码里根据不同的包名实现不同的功能,达到在不同的版本上屏蔽部分功能的目的。这个方法也很简单,通过getPackageName()接口获取当前应用的包名既可。