新闻详情

新闻详情

首页 / 资讯中心 / 详情

Activity通信全解析:Intent传参、事件总线与ViewModel选型

发布时间:2026/10/2 21:30:21来源:尧图网络
Activity通信全解析:Intent传参、事件总线与ViewModel选型
做安卓开发这几年我越来越确信一个判断Activity之间的通信是很多新手从“能写页面”跨到“会做业务”的第一道坎。哪怕是做了两三年的开发者遇到“详情页修改数据后列表页同步刷新”“登录态多页面共享”“复杂对象跨页面传递”这些需求也常常会停下来想一想到底该用哪种通信方式才靠谱。这个系列我一直在梳理安卓开发的实际场景这期就专门把Activity之间的通信方式从头到尾捋一遍。我先说一个最常见的例子列表页点一个item跳到详情页详情页里用户改了收藏状态返回之后列表页要把那条数据的状态同步过来。这个需求看起来简单但实现方案有好几种选错了后面就难受。Activity通信本质上就是“一个页面的数据怎么交给另一个页面”“另一个页面怎么把结果传回来”“多个页面怎么共享同一份状态”这三类问题。搞明白你面对的是哪类问题再选对应的方案代码才不会越写越乱。1. 通信方式全景梳理先想清楚你要传什么1.1 通信的核心不是“传数据”而是“传什么数据、传给谁、传完要干嘛”很多人一开始学Activity通信第一反应就是Intent觉得“跳转顺便带个参数”就是全部了。实际上Activity之间的通信可以按方向拆成四种情况第一种是正向传值就是A页面启动B页面把id、name、序列化对象传给B。这种是最基础的用Intent的putExtra就能解决。第二种是逆向回传B页面操作完了要把结果告诉A页面比如上面说的收藏状态变更。这种以前用startActivityForResult现在已经全面被Activity Result API取代。第三种是全局共享多个页面都要读同一份数据比如登录后的用户信息、主题设置、购物车状态。第四种是事件通知某个页面发生了某个动作其他页面需要感知并做出反应比如退出登录时所有页面都要清掉用户态这类场景就要靠事件总线或广播。把这四种情况分清楚之后选型就不是拍脑袋的事。我见过不少同事把全局共享的数据硬塞在Intent里来回传结果每个页面的启动代码都带着一大堆参数一旦字段加了或者改了编译不报错运行起来才发现漏传。也见过为了一个回传结果就上EventBus页面销毁的时候处理器没注销结果下次进入页面收到一堆旧事件。1.2 方案选型看四个维度数据量、生命周期、耦合度、作用域选通信方式我一般看四个维度。数据量很好理解传一个小对象的ID和传一个几百K的Bitmap完全是两个量级的问题后者根本不应该走Intent。生命周期指的是数据的存活时间是页面销毁就没了还是要一直存活到App退出。耦合度说的是发送方和接收方是不是必须明确互相知道A跳B这种天然就强耦合而登录状态变化通知所有页面这种就一定要解耦。作用域则要搞清楚这份数据是只在两个页面之间流动还是整个App共享。基于这些维度我平时有一个默认的选型表基本覆盖了日常90%的场景通信场景推荐方案原因正向传参跳转Intent Bundle简单直接类型安全生命周期跟随目标页面回传结果给上一页Activity Result API替代废弃的startActivityForResult类型安全代码清晰跨页面共享复杂对象Application或单例 持久化兜底生命周期覆盖整个进程避免每页传参跨模块解耦通知EventBus、LiveDataBus或局部广播发送方不依赖接收方扩缩容方便同页面内多Fragment共享状态共享ViewModel跟随Activity生命周期自动处理配置变更这套组合用下来大多数项目都不会出大问题。下面我一个个展开讲包括具体代码和为什么这么干。2. 最常用的Intent直传从传参到回传结果的完整方案2.1 显式Intent和隐式Intent别傻傻分不清Intent是Activity通信的基石但很多新人分不清显式和隐式。显式Intent就是明确指定要启动哪个类写法是Intent(this, SecondActivity::class.java)App内部页面跳转基本都是这个。隐式Intent则只声明一个Action或者Uri由系统根据IntentFilter去匹配能处理的组件比如拨打电话、打开网页、选择图片都属于隐式Intent。我个人的实践是App内部页面间通信老老实实用显式Intent不要图省事去搞自定义Action。原因很简单隐式Intent的解析是运行时的一旦系统里装了多个App声明了相同Action弹窗选择器就出来了。而显式Intent在编译期就锁死了目标类IDE还能帮你跳转重构类名也会自动改到引用处。显式Intent传参的标准写法是先构建Intent再用putExtra加数据。这里有一个细节容易被忽略putExtra是Intent调用的数据最终会打包进内部的Bundle。所以如果你有多个数据要传也可以直接创建一个Bundle把数据都塞进Bundle再putExtras(bundle)一次性带过去。两种方式等价但统一用Bundle的方式在参数多的时候更直观也好做统一管理。val intent Intent(this, DetailActivity::class.java).apply { putExtra(id, 10086) putExtra(name, 王小明) putExtra(source, home) } startActivity(intent)2.2 Bundle支持的数据类型以及Parcelable和Serializable的取舍Bundle能传的数据类型通常决定了你能往Intent里塞什么东西。支持的类型包括所有基本类型、String、CharSequence以及这些类型的数组和ArrayList还支持Serializable和Parcelable对象以及Bundle本身。这里面的坑点在于Serializable虽然写起来简单但性能差因为用到了反射和大量临时对象Parcelable是Android平台专有的序列化方案按格式写入Parcel性能好得多多用于内存间传递。所以结论很明确任何自定义对象要跨Activity传递优先实现Parcelable。Java手写Parcelable模板代码很繁琐现在Kotlin项目直接用Parcelize注解在build.gradle里加上kotlin-parcelize插件就行。Parcelize data class User( val id: Long, val name: String, val avatar: String? ) : Parcelable然后传递的时候val user User(10086, 王小明, null) val intent Intent(this, ProfileActivity::class.java).apply { putExtra(user, user) } startActivity(intent)接收方取数据就用intent.getParcelableExtra(user)。这里有个版本细节Android 13API 33上getParcelableExtra建议传入泛型参数也就是intent.getParcelableExtra(user, User::class.java)老写法在新系统上会出现类型安全警告部分厂商ROM还会直接报错。我在项目里已经把模板方法统一成带类型参数的新写法了。虽然Parcelable性能好但我还是建议一个原则能传ID就只传ID不要图省事把整个对象传过去。详情页拿到ID之后去本地库或者网络重新拉一次数据这样目标页展示的永远是最新数据也天然避开了对象过大导致的事务失败问题。2.3 用Activity Result API回传数据别再用startActivityForResult了回传结果这里我见过太多老代码还在用startActivityForResult onActivityResult setResult这套组合。在AndroidX Activity库升级之后google官方已经明确推荐Activity Result API。它解决了一个特别痛的问题回调不再散落在Activity的onActivityResult里而是注册和回调绑定在一起读代码的时候上下文是连续的。常规用法分三步。第一步在Activity的成员变量位置注册一个launcherprivate val detailLauncher registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result - if (result.resultCode RESULT_OK) { val name result.data?.getStringExtra(result_name) // 在这里处理返回的数据 } }第二步需要跳转的时候调用launchval intent Intent(this, EditActivity::class.java) detailLauncher.launch(intent)第三步在EditActivity里把结果通过setResult写回val resultIntent Intent().apply { putExtra(result_name, 修改后的名字) } setResult(RESULT_OK, resultIntent) finish()这个API还内置了好几个常用契约比如ActivityResultContracts.RequestPermission()可以用来请求运行时权限ActivityResultContracts.TakePicture()用来拍照ActivityResultContracts.GetContent()用来选图片。好处是回调永远和发起动作在同一个方法块里权限、图片选择、页面回传这些结果都能用同一套回调机制处理没有handleRequestPermissionsResult那一堆switch判断了。有一点必须注意registerForActivityResult必须在Activity处于STARTED状态之前注册通常写在成员变量位置或者onCreate里。如果你在按钮点击回调里才去注册运行时会直接抛IllegalStateException。另外如果在onResume之后才注册回调有可能会丢失。这个坑我踩过一次加了一堆代码排查半天最后发现只是注册时机不对。3. 全局共享与轻量级存储跨页面共享数据的三板斧3.1 自定义Application适合放进程级共享数据当同一份数据要被很多页面读取而且这些页面之间没有明确的父子跳转关系时再靠Intent一层层传就非常痛苦。我举一个真实的例子App里有一个用户画像对象底部导航五个Tab页面都要展示不同的画像字段如果每个Tab启动时都从入口页传参数过去改一个字段要动五六个文件。这时候把用户画像挂在Application上每页面自己取是最省事的。实现方式很简单写一个类继承Application在AndroidManifest里通过android:name指定class App : Application() { var currentUser: User? null }代码里拿Application实例val app application as App app.currentUser userActivity取的时候直接(application as App).currentUser。注意这里拿到的Application是进程级的它的生命周期覆盖App启动到退出所以放这里的对象不会因为页面销毁就丢。也正因为生命周期很长千万不要在Application里持有Activity的引用否则会导致Activity无法被回收内存泄漏马上就来。这个我后面在踩坑章节细说。3.2 静态变量和单例方便是真方便但有两个前提静态变量和单例本质上是一类东西都是把数据挂在类上而不是挂在某个页面实例上。它们的优点是拿取太方便了任何地方UserManager.getInstance().setUser(user)就行完全不依赖页面间传参。但用之前要搞清楚两个前提。第一个前提是进程存活静态数据存在内存里一旦进程被系统杀死数据就没了。所以登录状态、用户Token这种需要持久化的数据一定不能只放在静态变量里至少要同时存一份到SharedPreferences或者DataStore。第二个前提是防止Activity泄漏静态集合里如果持有了Activity引用比如用HashMap存Activity实例做统一管理就要确保Activity销毁时移除。LeakCanary能检测这种问题建议项目里常备。单例本身要线程安全。Kotlin的object声明天然是线程安全的比Java写双重检查锁省心得多。我现在的项目里临时性的共享数据都优先考虑Kotlin object单例但只拿它当内存缓存用从来不把单例里的数据当作唯一数据源。3.3 SharedPreferences兜底跨页面通信的“持久化保险丝”SharedPreferences虽然不算严格意义上的通信但它在Activity跨页面共享数据时频繁被用到因为很多状态是必须持久化的。最典型的就是登录态用户在登录页登录成功MainActivity需要知道用户名下次启动App还要保持登录。这种数据要是只放内存进程一死就回到未登录状态体验就很差了。我之前习惯用SharedPreferences存简单键值但现在新项目会优先考虑DataStore因为它基于Flow天然支持响应式而且没有apply和commit的异步同步割裂问题。不过老项目迁移DataStore成本不低SharedPreferences仍然大量存在于现有代码里。用SharedPreferences的时候记住一条读数据用getXxx写数据用edit().putXxx().apply()apply是异步写入适合不关心写入结果的场景如果要立刻拿到写入结果比如写完之后马上根据结果决定跳转用commit。别小看这个区别我在生产环境见过一次因为apply异步导致界面上数据显示不协调的线上问题排查了好久才定位到。4. 事件总线与广播解耦式通信的正确姿势4.1 EventBus发布订阅模型跨页面通知的好帮手前面说的方案基本都是“点对点”但业务里还有一种场景是“一对多”一个页面做了某件事好几个页面都得响应。比如用户把头像改了个人中心页、消息列表页、聊天页都要刷新头像用户退出登录所有页面都要清空用户态。这种需求如果靠Intent逐个通知代码会耦合得非常厉害而且很容易漏掉某个接收方。EventBus就是为解决这种问题出现的。它的核心思想是发布订阅发出一个事件所有注册了并且关心这个事件的页面都会收到回调。用起来三件事定义事件类、注册订阅者、发布事件。定义一个事件通常就是普通数据类data class AvatarChangedEvent(val userId: Long, val newUrl: String)在需要接收的Activity里注册和注销override fun onStart() { super.onStart() EventBus.getDefault().register(this) } override fun onStop() { EventBus.getDefault().unregister(this) super.onStop() } Subscribe(threadMode ThreadMode.MAIN) fun onAvatarChanged(event: AvatarChangedEvent) { // 拿到事件后刷新UI if (event.userId currentUserId) { avatarView.load(event.newUrl) } }发布事件就一行EventBus.getDefault().post(AvatarChangedEvent(userId, newUrl))要特别说明ThreadMode。ThreadMode.MAIN表示回调一定在主线程执行适合更新UIPOSTING表示和发布者同线程BACKGROUND和ASYNC用于耗时操作。我通常只在非常明确不需要操作UI的情况下才用非MAIN线程其余一律MAIN省心也避免线程切换引入的偶发问题。最关键的一点是注册和注销必须成对出现。最常见的泄漏就是Activity还在onStart注册了结果onStop忘了注销页面一走一进就注册了两次事件一来回调执行两遍而且匿名内部类形式的订阅者被EventBus持有引用GC回收不掉内存肉眼可见地涨。我建议在基类Activity里统一做register和unregister子类只关心业务这样能避免绝大多数的遗忘场景。4.2 LiveDataBus轻量级总线小项目够用EventBus功能强大但有人不喜欢引入第三方库或者项目本身已经在用Jetpack的LiveData那就用一个极简版的事件总线拿LiveData当总线。思路很简单用一张HashMap维护不同事件Key对应的MutableLiveData实例发送数据就是给对应的LiveData赋新值接收数据就是观察这个LiveData。object LiveDataBus { private val bus mutableMapOfString, MutableLiveDataAny() fun with(key: String): MutableLiveDataAny { return bus.getOrPut(key) { MutableLiveData() } } }发送方LiveDataBus.with(avatar_changed).value newAvatarUrl接收方LiveDataBus.with(avatar_changed).observe(this) { url - // 更新头像 }这方案比EventBus简单但也有局限。因为LiveData的特性是粘性的新的观察者一旦开始观察立刻会收到最近一次的值这在“事件”语境下反而不合适比如退出登录事件已经被消费了但稍后进入的页面还会收到一次导致重复处理。EventBus默认是没有粘性的所以如果是严格的“事件”通知LiveDataBus要自己做事件包装才能避免粘性问题。我的建议是简单调一下状态同步用LiveDataBus严谨的跨页面事件还是用EventBus或者下面说的广播。4.3 BroadcastReceiver系统级广播跨App才优先考虑有些场景比如耳机插拔、屏幕亮灭、网络切换、应用前后台是由系统发出的广播App想监听必须用BroadcastReceiver。但Activity之间的通信要不要用广播我的答案是慎重。广播的优势是系统全权接管跨App很方便。但同App内部用广播其实是给自己找麻烦一是需要定义Action字符串常量拼错一个字母就收不到二是很多新版本系统对隐式广播做了限制Android 8.0之后静态注册的隐式广播大部分被禁掉了动态注册的局部广播在App前后台切换时也可能收到不期望的系统级表三是广播回调里不能做耗时操作处理逻辑复杂了还得再派发线程。同App内部如果确实要用广播我建议用LocalBroadcastManager虽然现在官方标记为deprecated但它在内部用Handler分发比全局广播更安全更高效不用处理系统广播的打扰。不过新项目我更推荐只保留必要的系统广播监听业务通信一律走EventBus或者ViewModel广播这个方案在Activity之间的通信场景里作为备选即可。5. 架构化通信共享ViewModel与Navigation传参5.1 共享ViewModel让Activity和Fragment共享同一份状态很多同学把Activity通信等同于Intent传参直到项目变成单Activity多Fragment的架构才发现页面跳转变成了Fragment切换参数不能再靠startActivity传递了。这时候Jetpack的ViewModel为我们提供了一个优雅的通信方案声明一个ViewModel让同一个Activity下的多个Fragment共享它。做法很简单。先写一个普通的ViewModel把需要共享的数据用LiveData或者StateFlow包装class DetailSharedViewModel : ViewModel() { val commentCount MutableLiveData(0) val title MutableLiveData() }接着在Fragment里获取时指定使用Activity的ViewModelStoreOwnerval sharedViewModel: DetailSharedViewModel by viewModels({ requireActivity() })两个Fragment通过同一个requireActivity拿到的ViewModel是同一个实例。FragmentA改sharedViewModel.title的值FragmentB观察同一个LiveData就能立刻收到更新。这比在Fragment之间互相传SetArguments或者通过Activity再转发要清晰得多天然的观察者模式数据状态随Activity生命周期走Activity销毁自动清空不会泄漏。这个方案的适用场景需要明确它只适用于同一个Activity下的多个Fragment之间通信。如果是两个完全独立的Activity用共享ViewModel是拿不到同一个实例的。不过现代App的架构越来越偏向单Activity所以这个模式的覆盖范围其实很广。5.2 为什么共享ViewModel能自动避免内存泄漏ViewModel能在页面销毁后自动清理数据是因为AndroidX有一套完整的作用域机制。ViewModelStore是数据的容器它存在ViewModelStoreOwner上Activity或Fragment是ViewModelStoreOwner在销毁时如果是因为不可逆销毁系统会调用clear方法释放ViewModel里的资源协程的viewModelScope也会自动取消。这里我想强调的“为什么值得推荐”其实有两层。第一层是生命周期安全ViewModel持有数据但不会反向持有Activity视图层的引用所以配置变更比如旋转屏幕时Activity重建了ViewModel还是旧的数据不丢。第二层是代码整洁所有页面之间同步数据的逻辑都收敛在ViewModel里UI层只负责观察状态不再东一个setResult西一个getIntent去手动搬数据。如果你在做多Fragment项目我强烈建议把“Fragment之间传值”的常规思路切换成“共享ViewModel”的思路。它虽然没有Intent传参那么直接但后期维护的时候真的太省心了改一个状态不用翻遍所有相关的Fragment。5.3 Navigation组件下的Safe Args编译期类型安全的传参Jetpack Navigation是目前单Activity多Fragment项目的主流导航方案。它同样支持传参但我不建议手写Bundle的key因为字符串key写错了只有运行的时候才报错返回ClassCastException都算是运气好。官方提供的Safe Args插件能把传参变成类型安全的代码生成。在build.gradle里启用safe-args后定义路由的时候只要在nav_graph里声明参数字段fragment android:idid/detailFragment android:namecom.example.DetailFragment argument android:nameproductId app:argTypeinteger / /fragment跳转的时候就能用生成的Direction类val direction ProductListFragmentDirections .actionProductListFragmentToDetailFragment(productId 123) findNavController().navigate(direction)接收方也不需要手动解析BundleNavigation生成的FragmentArgs帮你处理val args DetailFragmentArgs.fromBundle(requireArguments()) val productId args.productId类型由编译期保证参数少了、类型错了直接编译不过。这种“把错误前移”的思路是我非常推崇的。如果你正在搭新项目并且确定走Navigation单Activity架构Safe Args应该是传参的首选不需要再手写一堆putExtra的代码。6. 踩坑实录与调优建议6.1 TransactionTooLargeExceptionIntent传大数据的边界Activity通信最常见也最隐蔽的崩溃就是TransactionTooLargeException。安卓的Intent跨进程Binder传输缓冲区有大小限制通常是1MB左右这1MB还包含binder事务开销。一旦你通过Intent传递了过大的对象——比如直接传一个几MB的Bitmap、一个超长的JSON字符串、一个包含上百条数据的列表——进程往系统进程写数据的时候就会爆掉而且是崩溃在startActivity那一行线上很不好排查。规避办法我在前面也提过最好的选择是不要传大数据本体只传一个ID或者本地文件路径。比如用相机拍照返回照片正确的姿势是先把照片存到App私有目录拿到UriIntent里传Uri回收方通过Uri读取。而不是把Bitmap塞进Intent里。还有列表页到详情页几百条数据想要一次性传过去我强烈建议改成分页拉取或者传一个查询条件。万一真的需要传一份不小的数据可以折中存到本地临时文件或者数据库目标页面启动后读取读完即删。虽然路径绕一些但稳定。6.2 静态引用导致的Activity泄漏Activity通信里还有一个很常见的坑在静态变量或者单例里保存了Activity引用。比如某些开发者喜欢维护一个Activity管理类用静态集合保存所有Activity实例方便统一finish。这么做如果remove时机不对Activity就会一直活在静态集合里即使页面已经销毁了内存也释放不了Activity持有的View树、Bitmap对象就全被拖住了。我的建议是不要用静态集合去管理Activity。需要统一退出的页面用finishAffinity或者非静态的本地管理就够了。而且在使用Application、单例这些长生命周期容器时统一原则是只存数据对象不存页面实例。即必须存Context也要用applicationContext绝不能存Activity。杀进程也没法完全避免这种泄漏的影响用户切几个页面内存就开始涨最后系统会杀掉App体验非常差。LeakCanary在debug包里必须加它能在Activity泄漏时直接弹通知告诉你哪里泄漏了省去大量排查时间。6.3 事件反注册遗漏导致重复回调与不可预知的界面刷新前面说过EventBus和BroadcastReceiver都必须成对注册反注册这里是实战里最容易遗漏的逻辑。常见的错误场景是用户在FragmentA注册了事件在进FragmentB时忘了反注册再加一个add()到返回栈于是栈里有两个页面同时订阅同一个事件。事件一发布匿名内部类的订阅者被持有旧页面虽然不可见但还活着双重刷新甚至旧页面弹出的Toast和对话框也能跟着出现。处理这类问题我有一套固定做法。第一基类里统一处理注册生命周期子类不感知。第二事件接收方法里判断宿主是否对用户可见不可见直接return。第三能不用事件就不用事件能用ViewModel基于生命周期自动清理的优先选择观察者模式。这些习惯能减少很多偶发线上问题。6.4 数据一致性与“页面已回收但数据还在”的错位另一个需要注意的点是跨页面共享数据时的一致性问题。比如Application里的用户对象被登录页改了但MainActivity的界面还缓存着旧数据就会出现“明明登录成功了界面上还是未登录”的情况。解决思路是给共享数据加上可观察性。如果用的是Application或单例不要只暴露普通字段可以暴露LiveData或StateFlow页面通过观察来同步。如果用的是SharedPreferences新项目直接用DataStore的Flow老项目则可以在写入后主动调用一次刷新回调。说到底跨页面通信不只是传数据更要考虑数据更新后的通知机制这两者合在一起才算一个完整的通信方案。我个人在实际操作中的体会是Activity通信没有银弹不同场景就是用不同方案强行用一种方式打天下项目大了必然要重构。入门先把Intent直传和Activity Result API吃透这是根基遇到共享状态再引入全局容器遇到一对多通知再上事件总线如果项目是单Activity多Fragment架构就直接把共享ViewModel和Safe Args作为主力方案。做选择的时候多想想“数据的生命周期有多少”“调用方和被调用方要不要解耦”大部分通信设计问题都能迎刃而解。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

稀疏奖励难题如何破?HER事后经验回放核心原理与工程实践全解 2026/10/2 23:07:06

稀疏奖励难题如何破?HER事后经验回放核心原理与工程实践全解

1. hindsight的两种指认:从“事后聪明”到算法命名 做强化学习这几年,我越来越觉得 hindsight 这个词比很多华丽术语都更能戳中我们做无模型算法时的痛点。它原意是“事后聪明”,也就是人们常说的“事后诸葛亮”——事情发生之后,…

阅读更多 →
Oracle EBS R12.2安装Step by Step实战指南 2026/10/2 23:06:50

Oracle EBS R12.2安装Step by Step实战指南

1. 这不是教科书,是我在客户现场踩了7次坑后写下的R12.2安装实录Oracle EBS R12.2安装——Step by Step,这八个字背后藏着的不是一套标准化流程,而是一整套需要在真实生产环境里反复校准、动态调整的系统工程。我干这行十二年,从R…

阅读更多 →
国内高校毕业生高频使用的AI写作辅助平台有哪些? 2026/10/2 23:06:49

国内高校毕业生高频使用的AI写作辅助平台有哪些?

国内高校学生常用的 AI 论文写作工具,以本土化全流程产品为主,结合通用大模型与专业辅助功能,覆盖选题、提纲、初稿、查重、降重、格式等关键环节,以下是主流工具详解与对比:一、本土全流程论文 AI 工具(中…

阅读更多 →
AI写作辅助网站8款AI论文写作工具势力榜,毕业冲刺必备! 2026/10/2 23:06:48

AI写作辅助网站8款AI论文写作工具势力榜,毕业冲刺必备!

论文写作是否总让你感到无从下手?文献资料繁杂难辨,思路迟迟无法成型?格式排版反复修改,查重结果却总是不理想? 别担心!AI论文写作工具的出现,正是为了解决这些困扰。本文将基于学术严谨性、文献…

阅读更多 →
移远BC28 NB-IoT模块AT指令实战指南 2026/10/2 23:06:47

移远BC28 NB-IoT模块AT指令实战指南

1. 项目概述:为什么BC28是NB-IoT落地的“稳态选择” 如果你正在做智能水表、烟感报警器、农业土壤监测节点,或者任何需要电池供电五年以上、部署在地下室/井盖下/偏远农田里的低功耗广域连接设备,那移远BC28大概率是你BOM清单里第一个被圈出来…

阅读更多 →
Altium元器件库上云实战:从本地SchLib迁移到Workspace的完整指南 2026/10/2 23:06:38

Altium元器件库上云实战:从本地SchLib迁移到Workspace的完整指南

元器件库管理这件事,说大不大,说小也真不小。画过几年板子的人大概都有体会:本地硬盘里躺着十几个版本的原理图库,命名从SchLib_old到SchLib_最终确认版_真的最终,同事之间靠聊天软件传来传去,谁改了哪个器…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉