在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

為項目添加KSP支持前需要注意的問題

谷歌開發者 ? 來源:Android 開發者 ? 作者:Android ? 2021-11-06 11:27 ? 次閱讀

Jetpack Room 庫在 SQLite 上提供了一個抽象層,能夠在沒有任何樣板代碼的情況下,提供編譯時驗證 SQL 查詢的能力。它通過處理代碼注解和生成 Java 源代碼的方式,實現上述行為。

Room

https://developer.android.google.cn/training/data-storage/room

注解處理器非常強大,但它們會增加構建時間。這對于用 Java 寫的代碼來說通常是可以接受的,但對于 Kotlin 而言,編譯時間消耗會非常明顯,這是因為 Kotlin 沒有一個內置的注解處理管道。相反,它通過 Kotlin 代碼生成了存根 Java 代碼來支持注解處理器,然后將其輸送到 Java 編譯器中進行處理。

由于并不是所有 Kotlin 源代碼中的內容都能用 Java 表示,因此有些信息會在這種轉換中丟失。同樣,Kotlin 是一種多平臺語言,但 KAPT 只在面向 Java 字節碼的情況下生效。

認識 Kotlin 符號處理

Kotlin 符號處理

https://github.com/google/ksp

隨著注解處理器在 Android 上的廣泛使用,KAPT 成為了編譯時的性能瓶頸。為了解決這個問題,Google Kotlin 編譯器團隊開始研究一個替代方案,來為 Kotlin 提供一流的注解處理支持。當這個項目誕生之初,我們非常激動,因為它將幫助 Room 更好地支持 Kotlin。從 Room 2.4 開始,它對 KSP 有了實驗性的支持,我們發現編譯速度提高了 2 倍,特別是在全量編譯的情況下。

本文內容重點不在注解的處理、Room 或者 KSP。而在于重點介紹我們在為 Room 添加 KSP 支持時所面臨的挑戰和所做的權衡。為了理解本文您并不需要了解 Room 或者 KSP,但必須熟悉注解處理。

注意: 我們在 KSP 發布穩定版之前就開始使用它了。因此,尚不確定之前做的一些決策是否適用于現在。

本篇文章旨在讓注解處理器的作者們在為項目添加 KSP 支持前,充分了解需要注意的問題。

Room 工作原理簡介

Room 的注解處理分為兩個步驟。有一些 “Processor” 類,它們遍歷用戶的代碼,驗證并提取必要的信息到 “值對象” 中。這些值對象被送到 “Writer” 類中,這些類將它們轉換為代碼。和其他諸多的注解處理器一樣,Room 非常依賴 Auto-Common 與 javax.lang.model 包 (Java 注解處理 API 包) 中頻繁引用的類。

Auto-Commonhttps://github.com/google/auto/tree/master/common

為了支持 KSP,我們有三種選擇:

復制 JavaAP 和 KSP 的每個 “Processor” 類,它們會有相同的值對象作為輸出,我們可以將其輸入到 Writer 中;

在 KSP/Java AP 之上創建一個抽象層,以便處理器擁有一個基于該抽象層的實現;

用 KSP 代替 JavaAP,并要求開發者也使用 KSP 來處理 Java 代碼。

選項 C 實際上是不可行的,因為它會對 Java 用戶造成嚴重的干擾。隨著 Room 使用數量的增加,這種破壞性的改變是不可能的。在 “A” 和 “B” 兩者之間,我們決定選擇 “B”,因為處理器具有相當數量的業務邏輯,將其分解并非易事。

認識 X-Processing

X-Processing

https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:room/room-compiler-processing/

在 JavaAP 和 KSP 上創建一個通用的抽象并非易事。Kotlin 和 Java 可以互操作,但模式卻不相同,例如,Kotlin 中特殊類的類型如 Kotlin 的值類或者 Java 中的靜態方法。此外,Java 類中有字段和方法,而 Kotlin 中有屬性和函數。

我們決定實現 “Room 需要什么”,而不是嘗試去追求完美的抽象。從字面意思來看,在 Room 中找到導入了 javax.lang.model 的每一個文件,并將其移動到 X-Processing 的抽象中。這樣一來,TypeElement 變成了 XTypeElement,ExecutableElemen 變成了 XExecutableElemen 等等。

遺憾的是,javax.lang.model API 在 Room 中的應用非常廣泛。一次性創建所有這些 X 類,會給審閱者帶來非常嚴重的心理負擔。因此,我們需要找到一種方法來迭代這一實現。

另一方面,我們需要證明這是可行的。所以我們首先對其做了原型設計,一旦驗證這是一個合理的選擇,我們就用他們自己的測試逐一重新實現了所有 X 類。

原型

https://android-review.googlesource.com/c/platform/frameworks/support/+/1362062

逐一重新實現了所有 X 類

https://android-review.googlesource.com/c/platform/frameworks/support/+/1362102

關于我說的實現 “Room 需要什么”,有一個很好的例子,我們可以在關于類的字段更改中看到。當 Room 處理一個類的字段時,它總是對其所有的字段感興趣,包括父類中的字段。所以我們在創建相應的 X-Processing API 時,只添加了獲取所有字段的能力。

interface XTypeElement { fun getAllFieldsIncludingPrivateSupers(): List《XVariableElement》}

更改https://android-review.googlesource.com/c/platform/frameworks/support/+/1362165/6/room/compiler-xprocessing/src/main/java/androidx/room/processing/javac/JavacTypeElement.kt

如果我們正在設計一個通用庫,這樣可能永遠不會通過 API 審查。但因為我們的目標只是 Room,并且它已經有一個與 TypeElement 具有相同功能的輔助方法,所以復制它可以減少項目的風險。

一旦我們有了基本的 X-Processing API 和它們的測試方法,下一步就是讓 Room 來調用這個抽象。這也是 “實現 Room 所需要的東西” 獲得良好回報的地方。Room 在 javax.lang.model API 上已經擁有了用于基本功能的擴展函數/屬性 (例如獲取 TypeElement 的方法)。我們首先更新了這些擴展,使其看起來與 X-Processing API 類似,然后在 1 CL 中將 Room 遷移到 X-Processing。

1 CLhttps://android-review.googlesource.com/c/platform/frameworks/support/+/1361181/21/room/compiler/src/main/kotlin/androidx/room/preconditions/Checks.kt

改進 API 可用性

保留類似 JavaAP 的 API 并不意味著我們不能改進任何東西。在將 Room 遷移到 X-Processing 之后,我們又實現了一系列的 API 改進。

例如,Room 多次調用 MoreElement/MoreTypes,以便在不同的 javax.lang.model 類型 (例如 MoreElements.asType) 之間進行轉換。相關調用通常如下所示:

val element: Element 。..if (MoreElements.isType(element)) { val typeElement:TypeElement = MoreElements.asType(element)}

MoreElements.asType

https://github.com/google/auto/blob/master/common/src/main/java/com/google/auto/common/MoreElements.java#L131

我們把所有的調用放到了 Kotlin contracts 中,這樣一來就可以寫成:

val element: XElement 。..if (element.isTypeElement()) { // 編譯器識別到元素是一個 XTypeElement}

Kotlin contracts

https://kotlinlang.org/docs/whatsnew13.html#contracts

另一個很好的例子是在一個 TypeElement 中找尋方法。通常在 JavaAP 中,您需要調用 ElementFilter 類來獲取 TypeElement 中的方法。與此相反,我們直接將其設為 XTypeElement 中的一個屬性。

// 前val methods = ElementFilter.methodsIn(typeElement.enclosedElements)// 后val methods = typeElement.declaredMethods

ElementFilter

https://docs.oracle.com/javase/7/docs/api/javax/lang/model/util/ElementFilter.html

最后一個例子,這也可能是我最喜歡的例子之一,就是可分配性。在 JavaAP 中,如果您要檢查給定的 TypeMirror 是否可以由另一個 TypeMirror 賦值,則需要調用 Types.isAssignable。

val type1: TypeMirror 。..val type2: TypeMirror 。..if (typeUtils.isAssignable(type1, type2)) { 。..}

Types.isAssignable

https://docs.oracle.com/javase/8/docs/api/javax/lang/model/util/Types.html#isAssignable-javax.lang.model.type.TypeMirror-javax.lang.model.type.TypeMirror-

這段代碼真的很難讀懂,因為您甚至無法猜到它是否驗證了類型 1 可以由類型 2 指定,亦或是完全相反的結果。我們已經有一個擴展函數如下:

fun TypeMirror.isAssignableFrom( types: Types, otherType: TypeMirror): Boolean

在 X-Processing 中,我們能夠將其轉換為 XType 上的常規函數,如下方所示:

interface XType { fun isAssignableFrom(other: XType): Boolean}

為 X-Processing 實現 KSP 后端

這些 X-Processing 接口每個都有自己的測試套件。我們編寫它們并非是用來測試 AutoCommon 或者 JavaAP 的,相反,編寫它們是為了在有了它們的 KSP 實現時,我們就可以運行測試用例來驗證它是否符合 Room 的預期。

AutoCommon

https://github.com/google/auto/tree/master/common

由于最初的 X-Processing API 是按照 avax.lang.model 建模,它們并非每次都適用于 KSP,所以我們也改進了這些 API,以便在需要時為 Kotlin 提供更好的支持。

這樣產生了一個新問題。現有的 Room 代碼庫是為了處理 Java 源代碼而寫的。當應用是由 Kotlin 編寫時,Room 只能識別該 Kotlin 在 Java 存根中的樣子。我們決定在 X-Processing 的 KSP 實現中保持類似行為。

例如,Kotlin 中的 suspend 函數在編譯時生成如下簽名:

// kotlinsuspend fun foo(bar:Bar):Baz// javaObject foo(bar:Bar, Continuation《? extends Baz》)

為保持相同的行為,KSP 中的 XMethodElement 實現為 suspend 方法合成了一個新參數,以及新的返回類型。(KspMethodElement.kt)

KspMethodElement.kt

https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt;l=108?q=KspSuspendMethodElement&ss=androidx

注意: 這樣做效果很好,因為 Room 生成的是 Java 代碼,即使在 KSP 中也是如此。當我們添加對 Kotlin 代碼生成的支持時,可能會引起一些變化。

另一個例子與屬性有關。Kotlin 屬性也可能具有基于其簽名的合成 getter/setter (訪問器)。由于 Room 期望找到這些訪問器作為方法 (參見: KspTypeElement.kt),因此 XTypeElement 實現了這些合成方法。

KspTypeElement.kt

https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt;l=144

注意: 我們已有計劃更改 XTypeElement API 以提供屬性而非字段,因為這才是 Room 真正想要獲取的內容。正如您現在猜到的那樣,我們決定 “暫時” 不這樣做來減少 Room 的修改。希望有一天我們能夠做到這一點,當我們這樣做時,XTypeElement 的 JavaAP 實現將會把方法和字段作為屬性捆綁在一起。

在為 X-Processing 添加 KSP 實現時,最后一個有趣的問題是 API 耦合。這些處理器的 API 經常相互訪問,因此如果不實現 XField / XMethod,就不能在 KSP 中實現 XTypeElement,而 XField / XMethod 本身又引用了 XType 等等。在添加這些 KSP 實現的同時,我們為它們的實現部分寫了單獨的測試用例。當 KSP 的實現變得更加完整時,我們逐漸通過 KSP 后端啟動全部的 X-Processing 測試。

需要注意的是,在此階段我們只在 X-Processing 項目中運行測試,所以即使我們知道測試的內容沒問題,我們也無法保證所有的 Room 測試都能通過 (也稱之為單元測試 vs 集成測試)。我們需要通過一種方法來使用 KSP 后端運行所有的 Room 測試,“X-Processing-Testing” 就應運而生。

認識 X-Processing-Testing

X-Processing-Testing

https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:room/room-compiler-processing-testing/

注解處理器的編寫包含 20% 的處理器代碼和 80% 的測試代碼。您需要考慮到各種可能的開發者錯誤,并確保如實報告錯誤消息。為了編寫這些測試,Room 已經提供一個輔助方法如下:

fun runTest( vararg javaFileObjects: JavaFileObject, process: (TestInvocation) -》 Unit): CompilationResult

runTest 在底層使用了 Google Compile Testing 庫,并允許我們簡單地對處理器進行單元測試。它合成了一個 Java 注解處理器并在其中調用了處理器提供的 process 方法。

val entitySource : JavaFileObject //示例 @Entity 注釋類val result = runTest(entitySource) { invocation -》 val element = invocation.processingEnv.findElement(“Subject”) val entityValueObject = EntityProcessor(。..).process(element) // 斷言 entityValueObject}// 斷言結果是否有誤,警告等

Google Compile Testing

https://github.com/google/compile-testing

糟糕的是,Google Compile Testing 僅支持 Java 源代碼。為了測試 Kotlin 我們需要另一個庫,幸運的是有 Kotlin Compile Testing,它允許我們編寫針對 Kotlin 的測試,而且我們為該庫貢獻了對 KSP 支持。

Kotlin Compile Testing

https://github.com/tschuchortdev/kotlin-compile-testing

注意: 我們后來用內部實現替換了 Kotlin Compile Testing,以簡化 AndroidX Repo 中的 Kotlin/KSP 更新。我們還添加了更好的斷言 API,這需要我們對 KCT 執行 API 不兼容的修改操作。

內部實現

https://android-review.googlesource.com/c/platform/frameworks/support/+/1779266

作為能讓 KSP 運行所有測試的最后一步,我們創建了以下測試 API:

fun runProcessorTest( sources: List《Source》, handler: (XTestInvocation) -》 Unit): Unit

這個和原始版本之間的主要區別在于,它同時通過 KSP 和 JavaAP (或 KAPT,取決于來源) 運行測試。因為它多次運行測試且 KSP 和 JavaAP 兩者的判斷結果不同,因此無法返回單個結果。

因此,我們想到了一個辦法:

fun XTestInvocation.assertCompilationResult( assertion: (XCompilationResultSubject) -》 Unit}

每次編譯后,它都會調用結果斷言 (如果沒有失敗提示,則檢查編譯是否成功)。我們把每個 Room 測試重構為如下所示:

val entitySource : Source //示例 @Entity 注釋類runProcessorTest(listOf(entitySource)) { invocation -》 // 該代碼塊運行兩次,一次使用 JavaAP/KAPT,一次使用 KSP val element = invocation.processingEnv.findElement(“Subject”) val entityValueObject = EntityProcessor(。..).process(element) // 斷言 entityValueObject invocation.assertCompilationResult { // 結果被斷言為是否有 error,warning 等 hasWarningContaining(“。..”) }}

接下來的事情就很簡單了。將每個 Room 的編譯測試遷移到新的 API,一旦發現新的 KSP / X-Processing 錯誤,就會上報,然后實施臨時解決方案;這一動作反復進行。由于 KSP 正在大力開發中,我們確實遇到了很多 bug。每一次我們都會上報 bug,從 Room 源鏈接到它,然后繼續前進 (或者進行修復)。每當 KSP 發布之后,我們都會搜索代碼庫來找到已修復的問題,刪除臨時解決方案并啟動測試。

一旦編譯測試覆蓋情況較好,我們在下一步就會使用 KSP 運行 Room 的集成測試。這些是實際的 Android 測試應用,也會在運行時測試其行為。幸運的是,Android 支持 Gradle 變體,因此使用 KSP 和 KAPT 來運行我們 Kotlin 集成測試便相當容易。

集成測試

https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:room/integration-tests/

Kotlin 集成測試

https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:room/integration-tests/kotlintestapp/build.gradle

下一步

將 KSP 支持添加到 Room 只是第一步。現在,我們需要更新 Room 來使用它。例如,Room 中的所有類型檢查都忽略了 nullability,因為 javax.lang.model 的 TypeMirror 并不理解 nullability。因此,當調用您的 Kotlin 代碼時,Room 有時會在運行時觸發 NullPointerException。有了 KSP,這些檢查現在可在 Room 中創建新的 KSP bug (例如 b/193437407)。我們已經添加了一些臨時解決方案,但理想情況下,我們仍希望改進 Room 以正確處理這些情況。

b/193437407

https://issuetracker.google.com/issues/193437407

改進

https://android-review.googlesource.com/c/platform/frameworks/support/+/1844471

同樣,即使我們支持 KSP,Room 仍然只生成 Java 代碼。這種限制使我們無法添加對某些 Kotlin 特性的支持,比如 Value Classes。希望在將來,我們還能對生成 Kotlin 代碼提供一些支持,以便在 Room 中為 Kotlin 提供一流的支持。接下來,也許更多 :)。

Value Classes

https://kotlinlang.org/docs/inline-classes.html

我能在我的項目上使用 X-Processing 嗎?

答案是還不能;至少與您使用任何其他 Jetpack 庫的方式不同。如前文所述,我們只實現了 Room 需要的部分。編寫一個真正的 Jetpack 庫有很大的投入,比如文檔、API 穩定性、Codelabs 等,我們無法承擔這些工作。話雖如此,Dagger 和 Airbnb (Paris、DeeplinkDispatch) 都開始用 X-Processing 來支持 KSP (并貢獻了他們需要的東西)。也許有一天我們會把它從 Room 中分解出來。從技術層面上講,您仍然可以像使用 Google Maven 庫一樣使用它,但是沒有 API 保證可以這樣做,因此您絕對應該使用 shade 技術。

Paris

https://github.com/airbnb/paris

DeeplinkDispatch

https://github.com/airbnb/DeepLinkDispatch

Google Maven 庫

https://maven.google.com/web/index.html#androidx.room

shade

https://github.com/johnrengelman/shadow

總結

我們為 Room 添加了 KSP 支持,這并非易事但絕對值得。如果您在維護注解處理器,請添加對 KSP 的支持,以提供更好的 Kotlin 開發者體驗。

特別感謝 Zac Sweers 和 Eli Hart 審校這篇文章的早期版本,他們同時也是優秀的 KSP 貢獻者。

Zac Sweers

https://medium.com/@ZacSweers

Eli Hart

https://medium.com/@konakid

更多資源

關于 Room 對于 KSP 支持的 Issue Tracker

https://issuetracker.google.com/issues/160322705

X-Processing 源碼

https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:room/room-compiler-processing/

X-Processing-Testing 源碼

https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:room/room-compiler-processing-testing/

KSP 源碼

https://github.com/google/ksp

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 處理器
    +關注

    關注

    68

    文章

    19404

    瀏覽量

    230965
  • 源代碼
    +關注

    關注

    96

    文章

    2946

    瀏覽量

    66894

原文標題:Room & Kotlin 符號的處理

文章出處:【微信號:Google_Developers,微信公眾號:谷歌開發者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    ADS1247想配置單端輸入,都需要注意哪些寄存器?

    這些開關是由哪些寄存器控制的,我在手冊里怎么沒有找到,我想配置單端輸入,不知道都需要注意哪些寄存器,在線等答案,望各位大俠幫忙
    發表于 01-15 08:31

    暢玩《黑神話:悟空》,除了“官配”硬件還需要注意這些......

    暢玩《黑神話:悟空》,除了“官配”硬件還需要注意這些......
    的頭像 發表于 08-30 14:58 ?521次閱讀
    暢玩《黑神話:悟空》,除了“官配”硬件還<b class='flag-5'>需要注意</b>這些......

    bnc公頭注塑需要注意什么

    德索工程師說道在BNC公頭注塑過程中,需要注意多個方面以確保產品的質量和生產效率。以下是對這一過程中關鍵注意事項的詳細闡述:   材料選擇:根據BNC公頭的使用環境和性能要求,選擇合適的注塑
    的頭像 發表于 08-22 08:53 ?291次閱讀
    bnc公頭注塑<b class='flag-5'>需要注意</b>什么

    短小精悍:5mV1kHz信號放大1000倍,需要注意什么?

    搭建電路需要注意項,以同相放大電路例:我需要將輸入信號(5mV,1kHz)的小信號進行放大,放大倍數1000倍,需要考慮什么?
    的頭像 發表于 08-12 18:08 ?5513次閱讀
    短小精悍:5mV1kHz信號放大1000倍,<b class='flag-5'>需要注意</b>什么?

    共模電感選型參數需要注意哪些

    電子發燒友網站提供《共模電感選型參數需要注意哪些.docx》資料免費下載
    發表于 07-30 14:23 ?0次下載

    存放高壓接線柱需要注意什么

    德索工程師說道在存放高壓接線柱時,我們需要注意幾個關鍵點以確保安全和設備的正常運行。我們要確保所有輔助電源都已斷開,避免意外送電的風險。
    的頭像 發表于 07-04 15:55 ?335次閱讀
    存放高壓接線柱<b class='flag-5'>需要注意</b>什么

    使用DCAC電源模塊時需要注意的事項

    BOSHIDA ?使用DC/AC電源模塊時需要注意的事項 1. 仔細閱讀和理解產品說明書:在使用DC/AC電源模塊之前,應該仔細閱讀和理解產品說明書,了解其性能特點、技術要求和使用方法,以確保
    的頭像 發表于 07-03 13:27 ?410次閱讀
    使用DCAC電源模塊時<b class='flag-5'>需要注意</b>的事項

    應用PLC需要注意哪些問題

    PLC(可編程邏輯控制器)作為現代工業控制的核心設備,其應用的廣泛性和重要性不言而喻。然而,在應用PLC的過程中,也需要注意一系列問題,以確保PLC系統的穩定運行和高效控制。本文將結合實際應用經驗,詳細探討應用PLC時需要注意的問題,并給出相應的解決策略和建議。
    的頭像 發表于 06-17 11:29 ?630次閱讀

    cyw43438是否支持開啟混雜模式?怎么使用wiced的接口打開呢?需要注意什么?

    如題,如果支持那應該怎么使用wiced的接口打開呢?需要注意什么?
    發表于 05-28 08:25

    FPGA的sata接口設計時需要注意哪些問題

    在FPGA的SATA接口設計時,需要注意以下幾個方面的問題,以確保設計的穩定性和性能: 接口版本和速度 : SATA有三代標準,分別為SATA I(1.5 Gb/s)、SATA II(3.0 Gb
    發表于 05-27 16:20

    PCBA加工生產時需要注意哪些相關事項?

    一站式PCBA智造廠家今天大家pcba批量生產過程中需要注意什么?pcba生產過程中需要注意的問題。PCBA(Printed Circuit Board Assembly)是電子產品生產過程
    的頭像 發表于 04-16 09:59 ?617次閱讀
    PCBA加工生產時<b class='flag-5'>需要注意</b>哪些相關事項?

    pcb電路板元件布局需要注意什么

    pcb電路板元件布局需要注意什么
    的頭像 發表于 03-14 15:24 ?940次閱讀

    激光焊接技術在焊接鋁合金時需要注意什么

    需要填充材料,減少了材料成本和加工時間。下面來看看激光焊接技術在焊接鋁合金時需要注意什么。 在激光焊接鋁合金時需要注意以下幾點: 1.清理焊縫表面:在焊接
    的頭像 發表于 02-29 13:43 ?926次閱讀
    激光焊接技術在焊接鋁合金時<b class='flag-5'>需要注意</b>什么

    智能手環設計需要注意哪些

    隨著電子技術的高速發展,可穿戴設備逐漸火爆,其中之一是智能手環,作為現代可穿戴技術的熱門產品之一,它集成了多種功能,如健康檢測、運動跟蹤、通知提醒等,為了實現這些功能,需要用上哪些電路模塊,在設計時需要注意哪些?下面一起來看看吧!
    的頭像 發表于 02-25 09:34 ?1027次閱讀

    使用電容降壓時都需要注意哪些?

    使用電容降壓時都需要注意哪些? 電容降壓是一種常見且廣泛應用的電路降壓方式,它可以將高電壓降低至設定的較低電壓,并且具有穩定、簡便、高效、可靠等優點。然而,在使用電容降壓時,我們需要注意一些關鍵
    的頭像 發表于 02-02 15:27 ?662次閱讀
    主站蜘蛛池模板: www.久久综合 | 色爽视频 | 国产福利不卡一区二区三区 | 黄色一级大片视频 | 久久午夜国产片 | 特黄特色大片免费视频大全 | 中国人69xxx大全 | 午夜色图 | 欧美黄色片在线观看 | 一区二区三区四区在线免费观看 | 手机看片自拍自自拍日韩免费 | 拍拍拍无档又黄又爽视频 | 天天视频色版 | 日本精品视频一视频高清 | 日本三级s级在线播放 | 亚洲a免费| 呦交小u女国产秘密入口 | 激情五月五月婷婷 | 在线观看精品国产入口 | 久久精品香蕉视频 | 爱搞逼综合 | 中文字幕导航 | 很黄很暴力 很污秽的小说 很黄很黄叫声床戏免费视频 | 亚洲v视频 | 成 人在线观看视频网站 | 四虎永久在线精品国产免费 | 高清视频免费观看 | 免费看你懂的 | 欧美黄色免费网站 | 午夜影院网页 | 四虎免费永久观看 | 一级一级一片免费高清 | 奇米7777第四色 | 五月六月激情 | 亚洲另类电击调教在线观看 | 精品国产污网站在线观看15 | 久久精品久噜噜噜久久 | 手机在线视频你懂的 | 国产哺乳期奶水avav | 狠狠色狠狠色综合 | 久久久久久国产精品免费免 |