01-18-01 Public API与SDK设计原则

张开发
2026/5/26 12:57:13 15 分钟阅读
01-18-01 Public API与SDK设计原则
01-18-01 Public API与SDK设计原则Public API是什么Public API是Android SDK中公开给开发者使用的接口。定义标准// Public API没有hide注解开发者可以直接使用publicclassActivityextendsContextThemeWrapper{publicvoidstartActivity(Intentintent){// ...}}API的三个层级1. Public API可见性所有应用可用// frameworks/base/core/java/android/app/Activity.javapackageandroid.app;/** Public API - 所有应用可用 */publicclassActivityextendsContextThemeWrapper{publicvoidonCreate(BundlesavedInstanceState){// 公开方法所有应用可调用}publicvoidstartActivity(Intentintent){// 公开方法}}特点包含在Android SDK中API文档公开永久向后兼容不能随意修改2. System APISystemApi可见性系统应用、特权应用可用// frameworks/base/core/java/android/app/ActivityManager.javapackageandroid.app;publicclassActivityManager{/** System API - 只有系统应用可用 */SystemApipublicvoidforceStopPackage(StringpackageName){// 强制停止应用普通应用不能调用}}特点需要系统签名或特权权限普通应用无法调用用于系统级功能3. Hidden APIhide可见性框架内部使用// frameworks/base/core/java/android/app/Activity.javapackageandroid.app;publicclassActivityextendsContextThemeWrapper{/** * hide Hidden API - 框架内部使用 */publicvoidperformCreate(BundlesavedInstanceState){// 内部方法开发者不应调用}}特点不包含在SDK中没有API文档可能随时修改或删除Android 9限制反射访问Android SDK设计原则1. 最小化原则Minimal API Surface只暴露必要的API// [未通过] 错误暴露过多实现细节publicclassImageLoader{publicHttpClientgetHttpClient(){}publicCachegetCache(){}publicThreadPoolgetThreadPool(){}publicDecodergetDecoder(){}}// [通过] 正确只暴露必要接口publicclassImageLoader{publicvoidload(Stringurl,ImageViewtarget){}publicvoidpreload(Stringurl){}publicvoidcancel(ImageViewtarget){}}Android实例// Activity只暴露必要方法publicclassActivity{// [通过] Public开发者需要publicvoidstartActivity(Intentintent){}publicvoidfinish(){}// [未通过] Hidden开发者不需要/** hide */publicvoidperformCreate(BundlesavedInstanceState){}}2. 稳定性原则API StabilityPublic API不能随意修改// [未通过] 错误修改Public API签名// Android 5.0publicvoidsetData(Stringdata){}// Android 6.0// public void setData(int data) { } // [未通过] 破坏兼容性// [通过] 正确添加重载方法publicvoidsetData(Stringdata){}publicvoidsetData(intdata){}// [通过] 新增重载实际案例Notification API演进// API 1-10简单通知NotificationnnewNotification(icon,tickerText,when);// API 11Builder模式新增不删除旧APINotificationnnewNotification.Builder(context).setContentTitle(Title).setContentText(Text).build();// API 26通知渠道强制要求但不删除旧APINotificationChannelchannelnewNotificationChannel(channel_id,Channel,NotificationManager.IMPORTANCE_DEFAULT);notificationManager.createNotificationChannel(channel);NotificationnnewNotification.Builder(context,channel_id).setContentTitle(Title).build();3. 语义化原则Semantic Naming命名清晰明确// [未通过] 错误命名不清publicclassMgr{}publicvoiddoIt(){}publicvoidprocess(){}// [通过] 正确语义明确publicclassNotificationManager{}publicvoidstartActivity(){}publicvoidregisterReceiver(){}Android命名规范// 动词开头动作startActivity()stopService()registerReceiver()// 名词获取状态getWindow()getApplicationContext()// is/has布尔判断isFinishing()hasWindowFocus()// set设置属性setContentView()setResult()4. 一致性原则Consistency相似功能使用相似模式// [通过] 一致的命名模式context.startActivity()context.startService()context.stopService()context.bindService()context.registerReceiver()context.unregisterReceiver()// [通过] 一致的参数顺序voidstartActivity(Intentintent)voidstartActivity(Intentintent,Bundleoptions)voidstartActivityForResult(Intentintent,intrequestCode)voidstartActivityForResult(Intentintent,intrequestCode,Bundleoptions)5. 向后兼容原则Backward Compatibility新版本不破坏旧代码// [通过] 正确使用targetSdkVersion控制行为if(getApplicationInfo().targetSdkVersionBuild.VERSION_CODES.M){// Android 6.0行为运行时权限checkRuntimePermission();}else{// Android 6.0以前行为安装时权限grantAllPermissions();}6. 可测试性原则Testability依赖接口而非实现// [未通过] 错误依赖具体实现publicclassLocationManager{publicLocationgetLastKnownLocation(){// 直接访问GPS硬件难以测试returngpsHardware.getLocation();}}// [通过] 正确依赖接口publicinterfaceLocationProvider{LocationgetLastKnownLocation();}publicclassLocationManager{privatefinalLocationProviderprovider;publicLocationManager(LocationProviderprovider){this.providerprovider;}publicLocationgetLastKnownLocation(){returnprovider.getLastKnownLocation();}}// 测试时可以MockclassMockLocationProviderimplementsLocationProvider{override fungetLastKnownLocation()Location(mock)}API设计实战案例1权限请求API设计Android 6.0以前// Manifest声明即可但不灵活uses-permission android:nameandroid.permission.CAMERA/Android 6.0// Activity.java - 运行时权限API设计// [通过] 简洁的请求APIpublicvoidrequestPermissions(String[]permissions,intrequestCode){// ...}// [通过] 统一的回调publicvoidonRequestPermissionsResult(intrequestCode,String[]permissions,int[]grantResults){// ...}// [通过] 检查权限publicintcheckSelfPermission(Stringpermission){// ...}// [通过] 是否应显示解释publicbooleanshouldShowRequestPermissionRationale(Stringpermission){// ...}使用示例// 请求相机权限if(checkSelfPermission(Manifest.permission.CAMERA)!PackageManager.PERMISSION_GRANTED){if(shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)){// 显示解释UI}requestPermissions(arrayOf(Manifest.permission.CAMERA),REQUEST_CAMERA)}overridefunonRequestPermissionsResult(requestCode:Int,permissions:ArrayString,grantResults:IntArray){if(requestCodeREQUEST_CAMERA){if(grantResults[0]PackageManager.PERMISSION_GRANTED){// 权限已授予}}}案例2RecyclerView API设计设计理念分离关注点// RecyclerView.java - 高内聚低耦合的API设计publicclassRecyclerViewextendsViewGroup{// [通过] 核心方法设置AdapterpublicvoidsetAdapter(Adapteradapter){}// [通过] 核心方法设置布局管理器publicvoidsetLayoutManager(LayoutManagerlayout){}// [通过] 扩展点设置装饰器publicvoidaddItemDecoration(ItemDecorationdecor){}// [通过] 扩展点设置动画publicvoidsetItemAnimator(ItemAnimatoranimator){}// [通过] 抽象类AdapterpublicstaticabstractclassAdapterVHextendsViewHolder{publicabstractVHonCreateViewHolder(ViewGroupparent,intviewType);publicabstractvoidonBindViewHolder(VHholder,intposition);publicabstractintgetItemCount();}// [通过] 抽象类LayoutManagerpublicstaticabstractclassLayoutManager{publicabstractvoidonLayoutChildren(Recyclerrecycler,Statestate);}}优点单一职责Adapter负责数据LayoutManager负责布局开闭原则通过继承扩展无需修改RecyclerView可测试性各部分可独立测试案例3LiveData API设计设计理念生命周期感知// LiveData.java - 生命周期感知的数据容器publicabstractclassLiveDataT{// [通过] 观察方法自动管理生命周期publicvoidobserve(NonNullLifecycleOwnerowner,NonNullObserverTobserver){// Activity/Fragment销毁时自动移除Observer}// [通过] 永久观察手动管理生命周期publicvoidobserveForever(NonNullObserverTobserver){// 需要手动removeObserver}// [通过] Protected子类设置值protectedvoidsetValue(Tvalue){// 主线程设置}protectedvoidpostValue(Tvalue){// 子线程设置}// [通过] Public获取当前值publicTgetValue(){returnmData;}}使用示例classUserViewModel:ViewModel(){privateval_userMutableLiveDataUser()valuser:LiveDataUser_user// 对外暴露不可变LiveDatafunloadUser(){_user.valuerepository.getUser()}}classUserActivity:AppCompatActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)viewModel.user.observe(this){user-// Activity销毁时自动取消观察无内存泄漏updateUI(user)}}}API Review流程Google的API Review设计阶段编写API设计文档内部Review团队内部审查API Council ReviewAndroid API委员会审查实现阶段实现并测试文档编写编写API文档和示例发布前Review最终审查API Review检查项✓ 是否符合最小化原则 ✓ 命名是否清晰 ✓ 是否与现有API一致 ✓ 是否考虑了向后兼容 ✓ 是否易于测试 ✓ 文档是否完善 ✓ 是否有示例代码 ✓ 是否考虑了性能影响 ✓ 是否考虑了安全性常见错误错误1暴露内部实现// [未通过] 暴露缓存实现classImageLoader{valcache:LruCacheString,Bitmapget()mCache// 暴露实现细节}// [通过] 隐藏实现classImageLoader{funclearCache(){mCache.evictAll()}// 只暴露行为}错误2过度设计// [未通过] 过度抽象interfaceImageLoadStrategy{}interfaceCacheStrategy{}interfaceDecodeStrategy{}interfaceTransformStrategy{}classImageLoader(valloadStrategy:ImageLoadStrategy,valcacheStrategy:CacheStrategy,valdecodeStrategy:DecodeStrategy,valtransformStrategy:TransformStrategy)// 过于复杂// [通过] 简单直接classImageLoader{funload(url:String):Bitmap{}}错误3忽略边界情况// [未通过] 没有参数校验funsetAlpha(alpha:Int){this.alphaalpha// 如果alpha0或255会怎样}// [通过] 参数校验funsetAlpha(alpha:Int){require(alphain0..255){Alpha must be between 0 and 255}this.alphaalpha}总结SDK设计六大原则最小化只暴露必要API稳定性Public API永久兼容语义化命名清晰明确一致性相似功能相似模式兼容性向后兼容可测试性依赖接口API层级Public API所有应用可用永久兼容System API系统应用专用Hidden API框架内部随时可变设计建议设计前充分思考发布后谨慎修改文档和示例完善考虑向后兼容简单胜于复杂关键要点API设计是一门艺术好的API简洁、稳定、易用一旦发布就很难修改

更多文章