Android SDK封装与发布实战指南
一、SDK架构分层实现
1. 业务调用层(API层)
作用:对外暴露简洁的调用接口
示例:入口类设计
public class MySDK {
privatestaticvolatile MySDK instance;
privatefinal Context appContext;
privatefinal SDKConfig config;
// 私有构造方法
private MySDK(Context context, SDKConfig config) {
this.appContext = context.getApplicationContext();
this.config = config;
initCoreComponents();
}
// 双重校验锁单例
public static void initialize(@NonNull Context context, @NonNull SDKConfig config) {
if (instance == null) {
synchronized (MySDK.class) {
if (instance == null) {
instance = new MySDK(context, config);
}
}
}
}
// 核心组件初始化
private void initCoreComponents() {
NetworkManager.init(config.getBaseUrl());
CacheDatabase.init(appContext);
}
// 业务接口示例:数据获取
public static void fetchUserData(String userId, DataCallback<JsonObject> callback) {
if (instance == null) thrownew IllegalStateException("SDK not initialized");
DataManager.getInstance().requestUserData(userId, callback);
}
}
2. 逻辑控制层(Service层)
作用:实现核心业务逻辑
示例:数据管理类
public class DataManager {
privatestatic DataManager instance;
privatefinal NetworkClient networkClient;
privatefinal LocalCache localCache;
public static synchronized DataManager getInstance() {
if (instance == null) {
instance = new DataManager();
}
return instance;
}
private DataManager() {
networkClient = NetworkClient.getInstance();
localCache = LocalCache.getInstance();
}
// 带缓存策略的数据请求
public void requestUserData(String userId, DataCallback<JsonObject> callback) {
// 先检查本地缓存
localCache.getUserData(userId, cachedData -> {
if (cachedData != null) {
callback.onSuccess(cachedData);
} else {
// 无缓存则发起网络请求
networkClient.get("/users/" + userId, new NetworkCallback() {
@Override
public void onSuccess(JsonObject response) {
localCache.saveUserData(userId, response);
callback.onSuccess(response);
}
@Override
public void onFailure(int code, String message) {
callback.onError(code, "Network error: " + message);
}
});
}
});
}
}
二、关键设计模式实现
1. Builder模式配置初始化
public class SDKConfig {
privatefinal String baseUrl;
privatefinalboolean debugMode;
privatefinalint maxCacheSize;
private SDKConfig(Builder builder) {
this.baseUrl = builder.baseUrl;
this.debugMode = builder.debugMode;
this.maxCacheSize = builder.maxCacheSize;
}
publicstaticclass Builder {
private String baseUrl = "https://api.default.com";
privateboolean debugMode = false;
privateint maxCacheSize = 1024; // MB
public Builder setBaseUrl(String url) {
this.baseUrl = url;
returnthis;
}
public Builder enableDebug(boolean enable) {
this.debugMode = enable;
returnthis;
}
public Builder setMaxCacheSize(int sizeMB) {
if (sizeMB > 0) this.maxCacheSize = sizeMB;
returnthis;
}
public SDKConfig build() {
returnnew SDKConfig(this);
}
}
// Getter方法省略...
}
使用方式:
SDKConfig config = new SDKConfig.Builder()
.setBaseUrl("https://api.example.com")
.enableDebug(BuildConfig.DEBUG)
.build();
MySDK.initialize(context, config);
三、核心难点解决方案
1. 安全上下文管理
完整实现类:
public class SafeContext {
privatestatic WeakReference<Context> appContextRef;
public static void init(Context context) {
if (context == null) return;
Context appContext = context.getApplicationContext();
appContextRef = new WeakReference<>(appContext);
}
public static Context get() {
if (appContextRef == null || appContextRef.get() == null) {
thrownew IllegalStateException("Context not initialized");
}
return appContextRef.get();
}
// 获取资源的安全方式
public static String getString(@StringRes int resId) {
return get().getString(resId);
}
}
2. 多线程任务调度
public class TaskExecutor {
privatestaticfinalint CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();
privatestaticfinal ExecutorService NETWORK_EXECUTOR =
new ThreadPoolExecutor(
CORE_POOL_SIZE,
CORE_POOL_SIZE * 2,
60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(50),
new CustomThreadFactory("network-")
);
privatestaticfinal Handler mainHandler =
new Handler(Looper.getMainLooper());
// 执行网络请求任务
public static void executeNetworkTask(Runnable task) {
NETWORK_EXECUTOR.execute(() -> {
try {
task.run();
} catch (Exception e) {
Log.e("TaskExecutor", "Network task failed", e);
}
});
}
// 切换到主线程
public static void runOnUiThread(Runnable action) {
if (Looper.myLooper() == Looper.getMainLooper()) {
action.run();
} else {
mainHandler.post(action);
}
}
// 自定义线程工厂
privatestaticclass CustomThreadFactory implements ThreadFactory {
privatefinal AtomicInteger counter = new AtomicInteger(1);
privatefinal String namePrefix;
CustomThreadFactory(String prefix) {
namePrefix = prefix;
}
public Thread newThread(Runnable r) {
returnnew Thread(r, namePrefix + counter.getAndIncrement());
}
}
}
四、资源隔离完整方案
1. 资源前缀配置
android {
resourcePrefix "sdk_"
}
2. 布局文件示例
<!-- sdk_user_profile.xml -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/sdk_avatar"
android:layout_width="48dp"
android:layout_height="48dp"/>
<TextView
android:id="@+id/sdk_username"
android:textAppearance="@style/sdk_TextAppearance.Title"/>
</LinearLayout>
3. 样式定义
<style name="sdk_TextAppearance.Title">
<item name="android:textSize">16sp</item>
<item name="android:textColor">#333</item>
</style>
五、完整依赖管理示例
1. 精准依赖配置
dependencies {
// 仅暴露必要API
api 'com.squareup.retrofit2:retrofit:2.9.0'
// 内部实现依赖
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
// 排除冲突依赖
implementation ('com.google.code.gson:gson:2.10.1') {
excludegroup: 'org.apache.httpcomponents'
}
// 本地依赖
implementation files('libs/third-party.aar')
}
2. 依赖冲突解决策略
configurations.all {
resolutionStrategy {
// 强制使用指定版本
force 'androidx.annotation:annotation:1.6.0'
// 自动排除重复依赖
eachDependency { details ->
if (details.requested.group == 'com.android.support') {
details.useVersion '28.0.0'
}
}
}
}
六、发布流程完整示例
1. Maven发布配置(带认证)
publishing {
publications {
maven(MavenPublication) {
groupId = 'com.techcompany'
artifactId = 'core-sdk'
version = '1.2.3'
// 自动包含所有产物
afterEvaluate {
artifact bundleReleaseAar
artifact sourcesJar
}
}
}
repositories {
maven {
url "https://nexus.example.com/repository/maven-releases/"
credentials {
username = System.getenv("MAVEN_USER")
password = System.getenv("MAVEN_PWD")
}
}
}
}
// 生成源码Jar
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
archiveClassifier = 'sources'
}
2. 版本控制策略
版本号规范:MAJOR.MINOR.PATCH
- 1.0.0:初始发布版本
- 1.1.0:新增用户画像分析功能(向后兼容)
- 2.0.0:重构网络层导致API不兼容
- 1.1.1:修复数据缓存失效问题
七、质量保障体系
1. 单元测试示例
@RunWith(MockitoJUnitRunner.class)
public class DataManagerTest {
@Mock
NetworkClient mockNetwork;
@Mock
LocalCache mockCache;
@Test
public void testCacheFirstStrategy() {
// 初始化被测试对象
DataManager manager = new DataManager(mockNetwork, mockCache);
// 模拟缓存命中
JsonObject testData = new JsonObject();
testData.addProperty("id", "1001");
when(mockCache.getUserData(anyString())).thenReturn(testData);
// 执行测试
manager.requestUserData("1001", new DataCallback<>() {
@Override
public void onSuccess(JsonObject data) {
assertEquals("1001", data.get("id").getAsString());
}
@Override
public void onError(int code, String msg) {
fail("Should not trigger error");
}
});
// 验证网络请求未触发
verify(mockNetwork, never()).get(anyString(), any());
}
}
2. 自动化文档生成
/**
* 用户数据回调接口
*
* <p>示例用法:</p>
* <pre>
* MySDK.fetchUserData("123", new DataCallback<JsonObject>() {
* {@literal @}Override
* public void onSuccess(JsonObject data) {
* // 处理数据
* }
* });
* </pre>
*/
public interface DataCallback<T> {
/**
* 操作成功回调
* @param data 返回的泛型数据对象
*/
void onSuccess(T data);
/**
* 操作失败回调
* @param code 错误码
* @param msg 错误描述
*/
void onError(int code, String msg);
}
文档生成命令:
./gradlew generateJavadoc
八、性能优化关键指标
1. 启动耗时检测
public class InitTimeTracker {
privatestaticlong startTime;
public static void startMeasure() {
startTime = SystemClock.elapsedRealtime();
}
public static void endMeasure() {
long duration = SystemClock.elapsedRealtime() - startTime;
if (duration > 100) {
Log.w("Perf", "SDK初始化耗时: " + duration + "ms");
}
}
}
// 在SDK初始化开始和结束处调用
public static void initialize(...) {
InitTimeTracker.startMeasure();
// ...初始化逻辑...
InitTimeTracker.endMeasure();
}
2. 内存占用监控
public class MemoryWatcher {
public static void checkMemoryUsage() {
Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memoryInfo);
if (memoryInfo.getTotalPss() > 5 * 1024) { // 5MB阈值
Log.e("Memory", "SDK内存占用过高: " + memoryInfo.getTotalPss() + "KB");
}
}
}
以上示例覆盖了SDK开发的关键环节,实际开发中需根据业务需求进行调整。建议重点注意:
接口的向后兼容性(使用@Deprecated渐进式升级)
做好API版本管理(使用版本适配器)
完善的日志系统(区分Debug/Release模式)
严格的权限控制(按需申请权限)
关注我获取更多知识或者投稿