Android Studio 不能識(shí)別基類中的方法

背景

  • Android Studio:
Android Studio Dolphin | 2021.3.1 Patch 1
  • Gradle:
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
  • AGP:
plugins {
    id 'com.android.application' version '7.2.2' apply false
    id 'com.android.library' version '7.2.2' apply false
    id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
}

問題

使用了 implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.8',其依賴了 implementation 'androidx.recyclerview:recyclerview:1.2.1',在新建的 MyAdapter 類中調(diào)用 RecyclerView.ViewHolder#getAdapterPosition() 方法時(shí),Android Studio 提示 can not resolve method
注意這里是不影響正常編譯和運(yùn)行的,只是 AS 的提示看著很煩人,而且不能自動(dòng)輔助彈出方法名。

can not resolve method.png

解決

可以以源碼依賴的方式解決,參考 Android 依賴項(xiàng)目外部文件夾中的工程 - 簡(jiǎn)書 (jianshu.com)

實(shí)驗(yàn)

為了弄清楚什么情況下會(huì)出現(xiàn)這種情況,做了如下實(shí)驗(yàn):
新建一個(gè) Test 工程,除 app 模塊外,再建一個(gè) lib-aar 模塊和 lib-rv 模塊,其中 lib-rv 模塊模擬 RecyclerView,lib-aar 模塊模擬 BaseRecyclerViewAdapterHelper。

| - app
    | - MyHolder1JavaExtendsJava.java
    | - MyHolder1JavaExtendsKotlin.java
    | - MyHolder1KotlinExtendsJava.kt
    | - MyHolder1KotlinExtendsKotlin.kt
    | - MyHolder2JavaExtendsJava.java
    | - MyHolder2JavaExtendsKotlin.java
    | - MyHolder2KotlinExtendsJava.kt
    | - MyHolder2KotlinExtendsKotlin.kt
| - lib-aar
    | - BaseHolder1Java.java
    | - BaseHolder1Kotlin.kt
    | - BaseHolder2Java.java
    | - BaseHolder2Kotlin.kt
| - lib-rv
    | - MyRecyclerView.java
    | - ViewHolder2.java
| - maven
  • MyRecyclerView.java
public class MyRecyclerView {

    public abstract static class ViewHolder1 {
        public int getAdapterPosition() {
            return 0;
        }
    }

}
  • ViewHolder2.java
public class ViewHolder2 {
    public int getAdapterPosition() {
        return 0;
    }
}
  • BaseHolder1Java.java
public class BaseHolder1Java extends MyRecyclerView.ViewHolder1 {
}
  • BaseHolder1Kotlin.kt
open class BaseHolder1Kotlin : ViewHolder1() {
}
  • BaseHolder2Java.java
public class BaseHolder2Java extends ViewHolder2 {
}
  • BaseHolder2Kotlin.kt
open class BaseHolder2Kotlin : ViewHolder2() {
}
  • MyHolder1JavaExtendsJava.java
public class MyHolder1JavaExtendsJava extends BaseHolder1Java {
    public void test() {
        int pos = this.getAdapterPosition();
    }
}
  • MyHolder1JavaExtendsKotlin.java 該文件提示 can not resolve method
public class MyHolder1JavaExtendsKotlin extends BaseHolder1Kotlin {
    public void test() {
        int pos = this.getAdapterPosition();
    }
}
  • MyHolder1KotlinExtendsJava.kt
class MyHolder1KotlinExtendsJava : BaseHolder1Java() {
    fun test() {
        val pos = this.getAdapterPosition()
    }
}
  • MyHolder1KotlinExtendsKotlin.kt
class MyHolder1KotlinExtendsKotlin : BaseHolder1Kotlin() {
    fun test() {
        val pos = this.getAdapterPosition()
    }
}
  • MyHolder2JavaExtendsJava.java
public class MyHolder2JavaExtendsJava extends BaseHolder2Java {
    public void test() {
        int pos = this.getAdapterPosition();
    }
}
  • MyHolder2JavaExtendsKotlin.java 該文正常
public class MyHolder2JavaExtendsKotlin extends BaseHolder2Kotlin {
    public void test() {
        int pos = this.getAdapterPosition();
    }
}
  • MyHolder2KotlinExtendsJava.kt
class MyHolder2KotlinExtendsJava : BaseHolder2Java() {
    fun test() {
        val pos = this.getAdapterPosition()
    }
}
  • MyHolder2KotlinExtendsKotlin.kt
class MyHolder2KotlinExtendsKotlin : BaseHolder2Kotlin() {
    fun test() {
        val pos = this.getAdapterPosition()
    }
}

結(jié)論

通過上面的對(duì)比可以發(fā)現(xiàn),當(dāng)我們有一個(gè)類 A,其繼承自一個(gè) aar 中(說明不是源碼引用)的類 B,而類 B 又繼承自一個(gè)類 C,那么當(dāng):

  • 類 A 以 java 代碼編寫
  • 類 B 以 kotlin 代碼編寫且位于 aar 中
  • 類 C 是一個(gè)內(nèi)部類

滿足以上三個(gè)條件時(shí),在 AS 中無(wú)法會(huì)出現(xiàn)在類 A 源碼中無(wú)法解析類 C 中的方法的情況,即類 A 中調(diào)用類 C 的方法,提示 can not resolve method

至此,算是知道了什么情況下會(huì)出現(xiàn)該問題,也知道了如何避免該問題的方法,要么以源碼形式依賴,要么避免出現(xiàn) A(java)=>B(kotlin)=>C(內(nèi)部類) 的情況即可。

至于為什么會(huì)出現(xiàn)此問題,還需要 Google 給出原因。。。

補(bǔ)充

上面推斷出是 A(java)=>B(kotlin)=>C(內(nèi)部類) 這種情況導(dǎo)致的,于是想到再找個(gè)普通的類進(jìn)行測(cè)試,想一想哪些類中有內(nèi)部類呢,首先想到的就是 FrameLayout$LayoutParams:

  • BaseLayoutParams.kt
open class BaseLayoutParams : FrameLayout.LayoutParams(0, 0) {
}
  • MyLayoutParamsJava.java 不正常
public class MyLayoutParamsJava extends BaseLayoutParams {
    public void test() {
        int g = this.gravity;
    }
}

MyLayoutParamsKotlin.kt 正常

class MyLayoutParamsKotlin : BaseLayoutParams() {
    fun test() {
        val g = this.gravity
    }
}
can not resolve symbol.png

果然,再次印證,當(dāng)遇到 A(java)=>B(kotlin)=>C(內(nèi)部類) 這種情況時(shí),AS 會(huì)出現(xiàn) can not resolve xxx 的 bug。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android studio我們那些年遇到的坑(一) 總結(jié)一下最近多年遇到的andorid studio重大問題,...
    龍_9b58閱讀 10,106評(píng)論 0 1
  • 用兩張圖告訴你,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 13,975評(píng)論 2 59
  • 1. 項(xiàng)目拉取下來(lái),開啟小飛機(jī),更新遠(yuǎn)程倉(cāng)庫(kù)aar失敗 解決方案:先關(guān)閉科學(xué)上網(wǎng)小飛機(jī),然后注釋掉項(xiàng)目中g(shù)radl...
    碼農(nóng)修行之路閱讀 2,239評(píng)論 0 0
  • 博客原文鏈接 Android百大框架排行榜(轉(zhuǎn)) 說明: 無(wú)聊寫一篇筆記式文章. 精力有限,很多錯(cuò)誤之處,受時(shí)間與...
    碼農(nóng)朱同學(xué)閱讀 3,116評(píng)論 0 27
  • 一.榜單介紹 排行榜包括四大類: 單一框架:僅提供路由、網(wǎng)絡(luò)層、UI層、通信層或其他單一功能的框架 混合開發(fā)框架:...
    偉子男閱讀 5,364評(píng)論 0 161

友情鏈接更多精彩內(nèi)容