Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Data Binding crash when using include tag with custom view layout

I'm trying to add some custom view using include tag to my activity layout which using DataBinding. My custom view is using DataBinding as well. But I got crash on application start:

05-02 17:30:03.685 12595-12595/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: com.novachevskyi.databindingtest, PID: 12595
                                                   java.lang.RuntimeException: Unable to start activity ComponentInfo{com.novachevskyi.databindingtest/com.novachevskyi.databindingtest.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.novachevskyi.databindingtest.databinding.CustomViewBinding.invalidateAll()' on a null object reference
                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                       at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                       at android.os.Looper.loop(Looper.java:148)
                                                       at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.novachevskyi.databindingtest.databinding.CustomViewBinding.invalidateAll()' on a null object reference
                                                       at com.novachevskyi.databindingtest.databinding.ActivityMainBinding.invalidateAll(ActivityMainBinding.java:41)
                                                       at com.novachevskyi.databindingtest.databinding.ActivityMainBinding.<init>(ActivityMainBinding.java:33)
                                                       at com.novachevskyi.databindingtest.databinding.ActivityMainBinding.bind(ActivityMainBinding.java:105)
                                                       at android.databinding.DataBinderMapper.getDataBinder(DataBinderMapper.java:11)
                                                       at android.databinding.DataBindingUtil.bind(DataBindingUtil.java:185)
                                                       at android.databinding.DataBindingUtil.bindToAddedViews(DataBindingUtil.java:299)
                                                       at android.databinding.DataBindingUtil.setContentView(DataBindingUtil.java:279)
                                                       at android.databinding.DataBindingUtil.setContentView(DataBindingUtil.java:261)
                                                       at com.novachevskyi.databindingtest.MainActivity.onCreate(MainActivity.java:11)
                                                       at android.app.Activity.performCreate(Activity.java:6251)
                                                       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
                                                       at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                       at android.os.Looper.loop(Looper.java:148) 
                                                       at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

MainActivity:

public class MainActivity extends AppCompatActivity {
  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    DataBindingUtil.setContentView(this, R.layout.activity_main);
  }
}

CustomView:

public class CustomView extends LinearLayout {
  public CustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override protected void onFinishInflate() {
    super.onFinishInflate();
    DataBindingUtil.bind(this);
  }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

  <RelativeLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:paddingLeft="@dimen/activity_horizontal_margin"
      android:paddingRight="@dimen/activity_horizontal_margin"
      android:paddingTop="@dimen/activity_vertical_margin"
      android:paddingBottom="@dimen/activity_vertical_margin"
      tools:context="com.novachevskyi.databindingtest.MainActivity">

    <include layout="@layout/custom_view"/>

  </RelativeLayout>

</layout>

custom_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android">

  <com.novachevskyi.databindingtest.CustomView
      android:layout_width="match_parent"
      android:layout_height="match_parent">

    <TextView
        android:text="Hello World!"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

  </com.novachevskyi.databindingtest.CustomView>

</layout>

I've also created public repo with sample project: https://github.com/novachevskyi/DataBinding-issue

I was using data binding with com.android.tools.build:gradle:1.3.1 and now, when I've tried to upgrade build tools version to com.android.tools.build:gradle:2.1.0, I'm facing such issue with all my views that contain include xml tag. Will appreciate for any information about issue described above.

like image 462
novachevskyi Avatar asked May 02 '16 14:05

novachevskyi


People also ask

Can I use both Data Binding and view Binding?

Data binding includes everything that ViewBinding has, so it wasn't designed to work side by side with View binding. The biggest issue is the naming conflict between the generated classes.

Which is better view Binding or Data Binding?

ViewBinding vs DataBindingThe main advantages of viewbinding are speed and efficiency. It has a shorter build time because it avoids the overhead and performance issues associated with DataBinding due to annotation processors affecting DataBinding's build time.

What is difference between ViewBinding and Binding Android?

View binding and data binding both generate binding classes that you can use to reference views directly. However, view binding is intended to handle simpler use cases and provides the following benefits over data binding: Faster compilation: View binding requires no annotation processing, so compile times are faster.

How do I convert layout to Data Binding layout?

To convert your XML layouts into the Data Binding layout, follow the below steps: Declare a <layout> tag, which will wrap your existing layout file at the root level. Declare variables under the <data> tag, which will go under the <layout> tag. Declare necessary expressions to bind data inside the view elements.


2 Answers

In case anyone else makes the er..dumb mistake I did...

This error was happening to me when I mistakenly had two duplicate layout files, one using databinding, and the other not...

Removing the duplicate fixed the error for me.

like image 118
jacoballenwood Avatar answered Oct 25 '22 14:10

jacoballenwood


I took a look at your project and ran it. I think the reason it is crashing is because of

@Override protected void onFinishInflate() {
    super.onFinishInflate();
    DataBindingUtil.bind(this);
}

if you remove DataBindingUtil.bind(this) it will stop crashing. The reason being that the bind call is looking for a <layout>surrounding the view but it can't find it so it throws an exception. Since the CustomView is calling bind on itself it is not surrounded by anything causing ViewDataBinding to throw new IllegalArgumentException("View is not a binding layout")

I'm not entirely sure what you're trying to achieve but calling bind inside of onFinishInflate would be redundant since the activity is doing that for you when it binds the layout for the activity. If you require the binding within the CustomView class you can do the following:

@Override protected void onAttachedToWindow() {
  super.onAttachedToWindow();
  CustomViewBinding binding = DataBindingUtil.findBinding(this);
}
like image 38
SeptimusX75 Avatar answered Oct 25 '22 12:10

SeptimusX75