Moi*_*han 12 java android build gradle android-studio
考虑我在我的android项目中有两个产品风味名为'local'和'international'. 我只是给出了我的情况的骨架,所以请不要理会其他错误. 考虑到我已经有不同的源Set为不同的味道.
现在我的'本地'味道我只需要下面提到的一种方法.
// local flavor file
interface UserDao {
List<User> getAllUser();
}
Run Code Online (Sandbox Code Playgroud)
虽然在我的国际风格,我还需要其他功能,以使用户也可以通过其名称进入组.所以有两种方法.
// international flavor file
interface UserDao {
List<User> getAllUser();
List<User> getAllUserGroupByName();
}
Run Code Online (Sandbox Code Playgroud)
但问题是,
我正在调用该方法的单个活动.
当我getAllUserGroupByName()从活动中调用方法时,如果当前的味道是' 国际 ',它将编译,但它不会编译' 本地 '味道,因为它不包含该方法.
我尝试通过如下条件包装来调用此方法,
// BuildUtils is my helper class to get current flavor check easily.
if (BuildUtils.isInternational()) {
getAppDatabase().UserDao().getAllUserGroupByName();
}
Run Code Online (Sandbox Code Playgroud)
但它也不起作用.
我不想要以下解决方案.
更新
经过@manouti的一些研究和回答
问题是Java是一种静态类型语言,因此放置if条件并不意味着编译器将避免使用getAllUserGroupByName调用来检查代码.
那么构建系统是否可以根据代码编译的风格忽略特定代码?
要么
任何Android工作室IDE工具或功能,将根据编译风格丢弃特定代码.
有几种方法可以做到这一点.当然,你可以像提到的另一个答案一样编写两个不同的Activity类,并将它们放在每个flavor的源集中,这样就可以了.但我认为你并不是真的想要这样做,因为复制代码可能是一种过度杀伤,两个版本之间的变化可能很小.
以下是我能想到的两种方法,允许您只保留一个Activity类(即在主源集中):
getAllUserGroupByName如果已定义,则使用反射调用方法.这篇文章的细节在这篇文章中有很好的说明.问题是Java是一种静态类型语言,因此放置if条件并不意味着编译器将避免使用getAllUserGroupByName调用来检查代码.使用此解决方案,您可以使用反射来检查方法是否已定义,如果已定义,则可以反射性地调用它.
IMO比使用反射代码更清洁的另一个解决方案是将用户组信息的检索逻辑封装在它自己的类和同一个包中,比如说UserGroupLoader,定义这个类的两个版本,每个版本一个.在本地风格中,实现将返回虚拟结果(例如,空的用户列表),并且在国际风格中它将使用加载用户的实际代码:
public class UserGroupInfoLoader {
public List<User> getAllUserGroupByName() {
// for international flavor, call UserDao.getAllUserGroupByName
// for local flavor, return empty list (you may even use the Optional class as a return type instead of List<User>)
}
}
Run Code Online (Sandbox Code Playgroud)您还可以控制要封装在此类中的逻辑范围.例如,您可以让它返回所有用户(第一个方法UserDao)和所有用户组合结果(仅适用于国际风味的实现),而不是仅返回用户组列表.这使得代码更具可读性,因为只有一个返回一种风格的虚拟数据的方法对于读者来说似乎是违反直觉的.
| 归档时间: |
|
| 查看次数: |
473 次 |
| 最近记录: |