on 08-04-2020 2:28 PM
Hi SAP Team,
I am trying to use databinding in conjunction with with the Object Header component, but it just partially works for me.
I can bind data to headline/subheadline/footnote etc., but as soon as I try to bind data to the status TextViews I added to the Object Header, I get the following Nullpointer Exception:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.apsolut.inbox.demo, PID: 8383
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.apsolut.inbox.demo/com.apsolut.inbox.ui.PRItemDetailActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setTag(java.lang.Object)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setTag(java.lang.Object)' on a null object reference
at com.apsolut.inbox.databinding.ItemDetailObjectHeaderBindingImpl.<init>(ItemDetailObjectHeaderBindingImpl.java:34)
at com.apsolut.inbox.databinding.ItemDetailObjectHeaderBindingImpl.<init>(ItemDetailObjectHeaderBindingImpl.java:25)
at com.apsolut.inbox.DataBinderMapperImpl.getDataBinder(DataBinderMapperImpl.java:44)
at androidx.databinding.MergedDataBinderMapper.getDataBinder(MergedDataBinderMapper.java:74)
at androidx.databinding.DataBindingUtil.bind(DataBindingUtil.java:199)
at androidx.databinding.ViewDataBinding.mapBindings(ViewDataBinding.java:1250)
at androidx.databinding.ViewDataBinding.mapBindings(ViewDataBinding.java:1266)
at androidx.databinding.ViewDataBinding.mapBindings(ViewDataBinding.java:1266)
at androidx.databinding.ViewDataBinding.mapBindings(ViewDataBinding.java:1266)
at androidx.databinding.ViewDataBinding.mapBindings(ViewDataBinding.java:717)
at com.apsolut.inbox.databinding.ItemPrDetailBindingImpl.<init>(ItemPrDetailBindingImpl.java:39)
at com.apsolut.inbox.DataBinderMapperImpl.getDataBinder(DataBinderMapperImpl.java:50)
at androidx.databinding.MergedDataBinderMapper.getDataBinder(MergedDataBinderMapper.java:74)
at androidx.databinding.DataBindingUtil.bind(DataBindingUtil.java:199)
at androidx.databinding.DataBindingUtil.bindToAddedViews(DataBindingUtil.java:327)
at androidx.databinding.DataBindingUtil.setContentView(DataBindingUtil.java:306)
at androidx.databinding.DataBindingUtil.setContentView(DataBindingUtil.java:284)
at com.apsolut.inbox.ui.PRItemDetailActivity.onCreate(PRItemDetailActivity.java:28)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
XML Object Header (This is an include file which works fine as long as I do not try to bind data to the Textviews):
<layout>
<data>
<variable
name="bodyText"
type="String" />
<variable
name="footnoteText"
type="String" />
<variable
name="headlineText"
type="String" />
<variable
name="subheadlineText"
type="String" />
<variable
name="statusText1"
type="String" />
<variable
name="statusText2"
type="String" />
<variable
name="descriptionText"
type="String" />
</data>
<com.sap.cloud.mobile.fiori.object.ObjectHeader 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:id="@+id/detail_object_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:body="@{bodyText ?? ``}"
app:dynamicStatusWidth="true"
app:footnote="@{footnoteText ?? ``}"
app:headline="@{headlineText ?? ``}"
app:description="@{descriptionText ?? ``}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:preserveDescriptionSpacing="false"
app:preserveDetailImageSpacing="false"
app:preserveIconImageContainer="false"
app:preserveIconStackSpacing="false"
app:subheadline="@{subheadlineText ?? ``}">
<TextView
android:id="@+id/object_header_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="@{statusText1 ?? ``}"
android:textColor="@color/white"
app:layout_header_group="STATUS" />
<TextView
android:id="@+id/object_header_prio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="5dp"
android:text="@{statusText2 ?? ``}"
android:textColor="@color/white"
app:layout_header_group="STATUS" />
</com.sap.cloud.mobile.fiori.object.ObjectHeader>
</layout>
Is this a bug within the component or do I have to apply the data through the Object Header instead of directly referencing the TextViews ?
Setting the data programmatically like this works for example:
objectHeader.setStatus("Status 1", 0);
objectHeader.setStatus("Status 2", 1);
Hope you can help me out.
Regards
Eduard
Hi Eduard,
The XML looks fine. The error message is complaining about setTag, which I cannot find in ObjectHeader or AbstractEntityCell. Can you double check where the `setTag` call comes from?
Thanks,
Hui Cao
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Hui,
The setTag call comes from ItemDetailObjectHeaderBindingImpl class which is generated by Android Studio based on the wrapped around <layout>-Tag where my ObjectHeader is located (see XML). The setTag() call is a method from class View which is being called in the generated Android binding class.
The error occurs in the second constructor referencing TextView with the id "object_header_prio" when Android tries to call this.objectHeaderPrio.setTag(null);
public ItemDetailObjectHeaderBindingImpl(@Nullable androidx.databinding.DataBindingComponent bindingComponent, @NonNull View root) {
this(bindingComponent, root, mapBindings(bindingComponent, root, 3, sIncludes, sViewsWithIds));
}
private ItemDetailObjectHeaderBindingImpl(androidx.databinding.DataBindingComponent bindingComponent, View root, Object[] bindings) {
super(bindingComponent, root, 0
, (com.sap.cloud.mobile.fiori.object.ObjectHeader) bindings[0]
, (android.widget.TextView) bindings[2]
, (android.widget.TextView) bindings[1]
);
this.detailObjectHeader.setTag(null);
this.objectHeaderPrio.setTag(null);
this.objectHeaderStatus.setTag(null);
setRootTag(root);
// listeners
invalidateAll();
}
It seems like the databinding implementation can not find the TextView implemented within the ObjectHeader or at least can not reference to the XML-View for some reason. Therefore this.objectHeaderPrio and this.objectHeaderStatus are being referenced as null which results in the displayed NullpointerException stacktrace, because we can not call setTag() on null.
But why is it not possible for Android to find the TextView within the ObjectHeader ?
I had a similiar issue directly referencing the TextViews by calling findViewById() for example and you are only able to receive those references by calling them like this through the generated object header object:
objectHeader.setStatus("Status 1", 0);
objectHeader.setStatus("Status 2", 1);
Maybe these issues are somehow related
Hi Eduard,
Now I see where the setTag call comes from. In our demo app, we also have a DataBinding sample activity, which is using ObjectCell, instead of ObjectHeader. But both of them are sharing the same logic in terms of status field. Once I added @+id/status_image for the status field in xml, I was able to see the reference to it in the generated code: this.statusImage.setTag(null);but it works fine in my environment. So what we can do is: 1. try to remove id and see whether it works around the issue; 2. can you share a sample project that can reproduce the issue?
Thanks,
Hui Cao
Hi Hui,
yes, it works fine with the Object cell component and I know the Object Header just inherits from Object Cell. I should have mentioned this before, sorry. But try to change to an Object Header and test it. I guarantee you it will not work. I don't know why, but something has to be different.
Regards
Eduard
Hi Eduard,
I reused your xml layout and created a simple Activity with the following code and it works fine. If you could share your files that'll make it easier to debug.
Thanks,
Hui Cao
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ItemDetailBinding binding = ItemDetailBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.setHeadlineText("Headline");
binding.setSubheadlineText("Subheadline");
binding.setStatusText1("Status1");
binding.setStatusText2("Status2");
}
Hi Eduard,
Now I'm able to reproduce the issue on a phone or tablet portrait mode. Previously I was testing on tablet landscape mode. The ObjectHeader uses ViewPager2 on phone or tablet portrait mode to layout child views, which in turn uses a RecyclerView to manage pages. RecyclerView does not add child views until it is laid out. While the data binding library tries to access the TextView right after ObjectHeader is constructed, which hasn't been laid out yet, therefore the reference becomes null.
At this moment, I don't have any workarounds for this issue. Please avoid using xml child views and data binding together for ObjectHeader.
Thanks,
Hui Cao
User | Count |
---|---|
85 | |
10 | |
10 | |
9 | |
6 | |
6 | |
6 | |
5 | |
4 | |
3 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.