无法使用findViewById访问自定义视图

时间:2019-05-09 21:38:13

标签: java android

我为ExoPlayer编写了一个小型包装程序,以抽象出一些实现细节并添加一些我们自己的业务逻辑。该包装器的签名如下所示:

public class BFPlayer extends PlayerView {

现在我有一个使用此视图的活动,我希望以编程方式访问该视图,以便可以在其上调用方法。这是我当前的代码:

public class PlayBroadcastActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_play_broadcast);

        BFPlayer player = findViewById(R.id.player);

        player.displayMessage("Test");
    }
}

此活动的XML:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".PlayBroadcastActivity">

    <com.blueframetech.bfplayer.BFPlayer
        android:id="@+id/player"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

这引发了错误:

> Task :app:compileDebugJavaWithJavac FAILED
/Users/stevenbarnett/Source/BluePlayer/AndroidSDK/app/src/main/java/com/blueframetech/blueframesdk/PlayBroadcastActivity.java:16: error: cannot access PlayerView
        BFPlayer player = findViewById(R.id.player);
                          ^
  class file for com.google.android.exoplayer2.ui.PlayerView not found
1 error

为什么会这样?该错误引用了com.google.android.exoplayer2.ui.PlayerView,但是我正在尝试访问PlayerView 子类 。为什么要尝试访问此第三方依赖库?而且,为什么尝试失败了?

1 个答案:

答案 0 :(得分:1)

为了使Java / Kotlin代码使用一个类,编译器需要访问继承层次结构中的所有类,因此它可以访问全部public个成员。由于BFPlayer扩展了PlayerViewBFPlayer的使用者需要访问PlayerView

但是,在包含BFPlayer的模块中,您已经使用implementation集成了ExoPlayer。这表示“为此模块使用此依赖关系,但不要将其标记为依赖于此模块的任何其他模块的传递依赖关系”。对于应用模块,implementation很好,因为没有其他模块依赖于该应用模块。

但是,BFPlayer在库模块中。因此,implementation阻止依赖于BFPlayer模块的模块访问ExoPlayer。

99.44%的时间,在库模块中,您希望您的主要依赖项使用api,而不是implementation,因此库模块的使用者还引入了其他(传递)依赖项

因此,将implementation模块中的api更改为BFPlayer,以获取ExoPlayer依赖关系(以及可能的任何其他依赖关系),您应该可以解决问题。