news 2026/5/12 9:16:47

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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 API(@SystemApi)

可见性:系统应用、特权应用可用

// frameworks/base/core/java/android/app/ActivityManager.javapackageandroid.app;publicclassActivityManager{/** System API - 只有系统应用可用 */@SystemApipublicvoidforceStopPackage(StringpackageName){// 强制停止应用,普通应用不能调用}}

特点

  • 需要系统签名或特权权限
  • 普通应用无法调用
  • 用于系统级功能

3. Hidden API(@hide)

可见性:框架内部使用

// 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 Stability)

Public API不能随意修改

// [未通过] 错误:修改Public API签名// Android 5.0publicvoidsetData(Stringdata){}// Android 6.0// public void setData(int data) { } // [未通过] 破坏兼容性// [通过] 正确:添加重载方法publicvoidsetData(Stringdata){}publicvoidsetData(intdata){}// [通过] 新增重载

实际案例:Notification API演进

// API 1-10:简单通知Notificationn=newNotification(icon,tickerText,when);// API 11+:Builder模式(新增,不删除旧API)Notificationn=newNotification.Builder(context).setContentTitle("Title").setContentText("Text").build();// API 26+:通知渠道(强制要求,但不删除旧API)NotificationChannelchannel=newNotificationChannel("channel_id","Channel",NotificationManager.IMPORTANCE_DEFAULT);notificationManager.createNotificationChannel(channel);Notificationn=newNotification.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().targetSdkVersion>=Build.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.provider=provider;}publicLocationgetLastKnownLocation(){returnprovider.getLastKnownLocation();}}// 测试时可以MockclassMockLocationProviderimplementsLocationProvider{override fungetLastKnownLocation()=Location("mock")}

API设计实战

案例1:权限请求API设计

Android 6.0以前

// Manifest声明即可,但不灵活<uses-permission android:name="android.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:Array<String>,grantResults:IntArray){if(requestCode==REQUEST_CAMERA){if(grantResults[0]==PackageManager.PERMISSION_GRANTED){// 权限已授予}}}

案例2:RecyclerView API设计

设计理念:分离关注点

// RecyclerView.java - 高内聚低耦合的API设计publicclassRecyclerViewextendsViewGroup{// [通过] 核心方法:设置AdapterpublicvoidsetAdapter(Adapteradapter){}// [通过] 核心方法:设置布局管理器publicvoidsetLayoutManager(LayoutManagerlayout){}// [通过] 扩展点:设置装饰器publicvoidaddItemDecoration(ItemDecorationdecor){}// [通过] 扩展点:设置动画publicvoidsetItemAnimator(ItemAnimatoranimator){}// [通过] 抽象类:AdapterpublicstaticabstractclassAdapter<VHextendsViewHolder>{publicabstractVHonCreateViewHolder(ViewGroupparent,intviewType);publicabstractvoidonBindViewHolder(VHholder,intposition);publicabstractintgetItemCount();}// [通过] 抽象类:LayoutManagerpublicstaticabstractclassLayoutManager{publicabstractvoidonLayoutChildren(Recyclerrecycler,Statestate);}}

优点

  • 单一职责:Adapter负责数据,LayoutManager负责布局
  • 开闭原则:通过继承扩展,无需修改RecyclerView
  • 可测试性:各部分可独立测试

案例3:LiveData API设计

设计理念:生命周期感知

// LiveData.java - 生命周期感知的数据容器publicabstractclassLiveData<T>{// [通过] 观察方法:自动管理生命周期publicvoidobserve(@NonNullLifecycleOwnerowner,@NonNullObserver<T>observer){// Activity/Fragment销毁时自动移除Observer}// [通过] 永久观察:手动管理生命周期publicvoidobserveForever(@NonNullObserver<T>observer){// 需要手动removeObserver}// [通过] Protected:子类设置值protectedvoidsetValue(Tvalue){// 主线程设置}protectedvoidpostValue(Tvalue){// 子线程设置}// [通过] Public:获取当前值publicTgetValue(){returnmData;}}

使用示例

classUserViewModel:ViewModel(){privateval_user=MutableLiveData<User>()valuser:LiveData<User>=_user// 对外暴露不可变LiveDatafunloadUser(){_user.value=repository.getUser()}}classUserActivity:AppCompatActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)viewModel.user.observe(this){user->// Activity销毁时自动取消观察,无内存泄漏updateUI(user)}}}

API Review流程

Google的API Review

  1. 设计阶段:编写API设计文档
  2. 内部Review:团队内部审查
  3. API Council Review:Android API委员会审查
  4. 实现阶段:实现并测试
  5. 文档编写:编写API文档和示例
  6. 发布前Review:最终审查

API Review检查项

✓ 是否符合最小化原则? ✓ 命名是否清晰? ✓ 是否与现有API一致? ✓ 是否考虑了向后兼容? ✓ 是否易于测试? ✓ 文档是否完善? ✓ 是否有示例代码? ✓ 是否考虑了性能影响? ✓ 是否考虑了安全性?

常见错误

错误1:暴露内部实现

// [未通过] 暴露缓存实现classImageLoader{valcache:LruCache<String,Bitmap>get()=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.alpha=alpha// 如果alpha<0或>255会怎样?}// [通过] 参数校验funsetAlpha(alpha:Int){require(alphain0..255){"Alpha must be between 0 and 255"}this.alpha=alpha}

总结

SDK设计六大原则

  1. 最小化:只暴露必要API
  2. 稳定性:Public API永久兼容
  3. 语义化:命名清晰明确
  4. 一致性:相似功能相似模式
  5. 兼容性:向后兼容
  6. 可测试性:依赖接口

API层级

  • Public API:所有应用可用,永久兼容
  • System API:系统应用专用
  • Hidden API:框架内部,随时可变

设计建议

  • 设计前充分思考
  • 发布后谨慎修改
  • 文档和示例完善
  • 考虑向后兼容
  • 简单胜于复杂

关键要点:API设计是一门艺术,好的API简洁、稳定、易用,一旦发布就很难修改

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 21:39:16

Ryujinx实战指南:从入门到精通的四大核心技能

Ryujinx实战指南&#xff1a;从入门到精通的四大核心技能 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx Ryujinx作为一款采用C#语言开发的开源Nintendo Switch模拟器&#xff0c;能够…

作者头像 李华
网站建设 2026/4/17 1:48:04

17.1k stars!手机就是你的 AI 服务器:Google AI Edge Gallery 完全解析!

手机就是你的 AI 服务器:Google AI Edge Gallery 完全解析 当大模型不再需要云端,隐私与智能可以同时拥有。 一、我们一直在忍受什么? 打开手机上的 AI 应用,你可能习以为常地接受这些事: 必须联网,没有信号就没有智能 数据上传云端,你的对话、图片、录音都在别人的服务…

作者头像 李华
网站建设 2026/4/13 15:26:31

JMS, ActiveMQ 学习一则寐

开发个什么Skill呢&#xff1f; 通过 Skill&#xff0c;我们可以将某些能力进行模块化封装&#xff0c;从而实现特定的工作流编排、专家领域知识沉淀以及各类工具的集成。 这里我打算来一次“套娃式”的实践&#xff1a;创建一个用于自动生成 Skill 的 Skill&#xff0c;一是用…

作者头像 李华
网站建设 2026/4/14 7:12:51

Flutter + 鸿蒙跨平台开发实战:从零构建中学生生活模拟器(初)

**欢迎加入开源鸿蒙跨平台社区&#xff1a; https://openharmonycrossplatform.csdn.net 大家好&#xff01;我接下来将会继续分享关于flutter与鸿蒙跨平台开发中遇到的一些问题以及如何解决的。 首先本篇主要是围绕继在完成所有前置操作后进行的&#xff0c;要安装Git&#xf…

作者头像 李华
网站建设 2026/4/17 13:57:18

突破Cursor使用限制:开源工具实现无限试用与高效编程的完整指南

突破Cursor使用限制&#xff1a;开源工具实现无限试用与高效编程的完整指南 【免费下载链接】go-cursor-help 解决Cursor在免费订阅期间出现以下提示的问题: Your request has been blocked as our system has detected suspicious activity / Youve reached your trial reques…

作者头像 李华