如何使用模块创建库?
How to create library with modules?
我想创建几个库(核心和模块),将所有这些库添加到应用程序并从核心库中的模块调用方法。所有模块都应该是可选的。例如,如我所见:
申请build.gradle
:
compile('core-library:1.0@aar')
compile('module1-library:1.0@aar')
compile('module2-library:1.0@aar')
compile('module3-library:1.0@aar')
在每个模块中定义 class 和同名方法:
public class ModuleClass {
public int moduleMethod1() {
// Do something and return result
return 1;
}
public String moduleMethod2() {
return "Some String";
}
}
在核心库中:
for(ModuleClass c : getAllModules()) {
Log.d("tag", "Result: " + c.moduleMethod1() + " / " + c.moduleMethod2();
}
当然那只是伪代码。怎么实现之类的?
已更新:
核心模块build.gradle
:
apply plugin: 'com.android.library'
android {
compileSdkVersion 24
buildToolsVersion "24.0.3"
defaultConfig {
minSdkVersion 9
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
buildConfigField "String[]", "KNOWN_MODULES", "{" +
"\"module1\"," +
"\"module2\"" +
"}"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compileOnly project(':module1')
compileOnly project(':module2')
testCompile 'junit:junit:4.12'
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
}
您可以尝试在 core-library
中添加 List<Class>
。当您尝试加载列表时必须非常小心,但您应该能够做到。
首先,您的 moduleN-library
需要 compileOnly
,这样它就不会与 core-library
.
捆绑在一起
然后在你的 core-library
中保留一个单例,它安全地列出所有可能的模块 类。
package com.jbirdvegas.test;
import java.util.HashMap;
import java.util.Map;
public class ModuleClassManager {
private static final Object LOCK = new Object();
private static ModuleClassManager instance;
private Map<Class, Methods> moduleClasses = new HashMap<>();
private ModuleClassManager() {
try {
moduleClasses.put(MayNotExist1.class, new MayNotExist1());
} catch (Exception ignored) {
}
try {
moduleClasses.put(MayNotExist2.class, new MayNotExist2());
} catch (Exception ignored) {
}
try {
moduleClasses.put(MayNotExist3.class, new MayNotExist3());
} catch (Exception ignored) {
}
}
public static ModuleClassManager getInstance() {
if (instance == null) {
synchronized (LOCK) {
instance = new ModuleClassManager();
}
}
return instance;
}
public void callMethodOnAll() {
moduleClasses.forEach((aClass, methods) -> methods.methodOne());
}
// the below interface in the real world would be located
// in the `core-library` and the classes that implement the
// interface, `Methods` in this example, would exist in the
// module's they represent.
interface Methods {
void methodOne();
}
class MayNotExist1 implements Methods {
@Override
public void methodOne() {
}
}
class MayNotExist2 implements Methods {
@Override
public void methodOne() {
}
}
class MayNotExist3 implements Methods {
@Override
public void methodOne() {
}
}
}
或者...使用 OSGi。 OSGi 的设置更复杂,但它可以非常好地处理这个用例。
我想创建几个库(核心和模块),将所有这些库添加到应用程序并从核心库中的模块调用方法。所有模块都应该是可选的。例如,如我所见:
申请build.gradle
:
compile('core-library:1.0@aar')
compile('module1-library:1.0@aar')
compile('module2-library:1.0@aar')
compile('module3-library:1.0@aar')
在每个模块中定义 class 和同名方法:
public class ModuleClass {
public int moduleMethod1() {
// Do something and return result
return 1;
}
public String moduleMethod2() {
return "Some String";
}
}
在核心库中:
for(ModuleClass c : getAllModules()) {
Log.d("tag", "Result: " + c.moduleMethod1() + " / " + c.moduleMethod2();
}
当然那只是伪代码。怎么实现之类的?
已更新:
核心模块build.gradle
:
apply plugin: 'com.android.library'
android {
compileSdkVersion 24
buildToolsVersion "24.0.3"
defaultConfig {
minSdkVersion 9
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
buildConfigField "String[]", "KNOWN_MODULES", "{" +
"\"module1\"," +
"\"module2\"" +
"}"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compileOnly project(':module1')
compileOnly project(':module2')
testCompile 'junit:junit:4.12'
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
}
您可以尝试在 core-library
中添加 List<Class>
。当您尝试加载列表时必须非常小心,但您应该能够做到。
首先,您的 moduleN-library
需要 compileOnly
,这样它就不会与 core-library
.
然后在你的 core-library
中保留一个单例,它安全地列出所有可能的模块 类。
package com.jbirdvegas.test;
import java.util.HashMap;
import java.util.Map;
public class ModuleClassManager {
private static final Object LOCK = new Object();
private static ModuleClassManager instance;
private Map<Class, Methods> moduleClasses = new HashMap<>();
private ModuleClassManager() {
try {
moduleClasses.put(MayNotExist1.class, new MayNotExist1());
} catch (Exception ignored) {
}
try {
moduleClasses.put(MayNotExist2.class, new MayNotExist2());
} catch (Exception ignored) {
}
try {
moduleClasses.put(MayNotExist3.class, new MayNotExist3());
} catch (Exception ignored) {
}
}
public static ModuleClassManager getInstance() {
if (instance == null) {
synchronized (LOCK) {
instance = new ModuleClassManager();
}
}
return instance;
}
public void callMethodOnAll() {
moduleClasses.forEach((aClass, methods) -> methods.methodOne());
}
// the below interface in the real world would be located
// in the `core-library` and the classes that implement the
// interface, `Methods` in this example, would exist in the
// module's they represent.
interface Methods {
void methodOne();
}
class MayNotExist1 implements Methods {
@Override
public void methodOne() {
}
}
class MayNotExist2 implements Methods {
@Override
public void methodOne() {
}
}
class MayNotExist3 implements Methods {
@Override
public void methodOne() {
}
}
}
或者...使用 OSGi。 OSGi 的设置更复杂,但它可以非常好地处理这个用例。