마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

LiveData, DataBinding 오류

0 추천

안녕하세요

https://www.masterqna.com/android/101879/livedata-%EC%82%AC%EC%9A%A9%EB%B0%A9%EB%B2%95

이전에 질문한 내용에 데이터바인딩을 적용시켜봤습니다.

알맞게 한 것인지 모르겠습니다. 실행은 되지만 오류가 있습니다. 왜 그런 건가요..?

 

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

    <data>
        <import type="android.view.View" />
        <variable
            name="mymain"
            type="com.psw.mylivedata.NameViewModel" />
    </data>
    <LinearLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <EditText
                android:id="@+id/nameInput"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ems="10"
                android:inputType="textPersonName"
                android:text="Name" />

            <Button
                android:id="@+id/inputButton"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:text="Button"
                android:onClick="@{()->mymain.btnClick(nameInput.getText().toString())}"/>
        </LinearLayout>

        <TextView
            android:id="@+id/nameText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TextView" />
    </LinearLayout>
</layout>

Main

public class MainActivity extends AppCompatActivity {
    public NameViewModel nameViewModel;
    public ActivityMainBinding mainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);

        //ViewModel 생성
        nameViewModel = new ViewModelProvider(this)
                .get(NameViewModel.class);


        mainBinding.setMymain(nameViewModel);
   
        Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(String newName) {
                mainBinding.nameText.setText(newName);
            }
        };
        //ViewModel에 옵저버 등록
        nameViewModel.getCurrentName().observe(this,nameObserver);
    }

}

ViewModel

public class NameViewModel extends ViewModel {
    private MutableLiveData<String> currentName;
    public LiveData<String> getCurrentName(){
        if(currentName == null){
            currentName = new MutableLiveData<String>();
        }
        return currentName;
    }
    public void onNameChanged(String name) {
        currentName.postValue(name);
    }

    public void btnClick(String str){
        onNameChanged(str);
    }
}

 

ViewModel에서 related problems 문제가 2개 발생했다고 나옵니다. 

오류를 클릭하면 아래와 같은 파일로 이동합니다.

여기서 첫번째줄 ActivityMainBinding 과 mMymain이 모두 오류라고 나옵니다.

public class ActivityMainBindingImpl extends ActivityMainBinding implements com.psw.mylivedata.generated.callback.OnClickListener.Listener {

    @Nullable
    private static final androidx.databinding.ViewDataBinding.IncludedLayouts sIncludes;
    @Nullable
    private static final android.util.SparseIntArray sViewsWithIds;
    static {
        sIncludes = null;
        sViewsWithIds = new android.util.SparseIntArray();
        sViewsWithIds.put(R.id.nameInput, 2);
        sViewsWithIds.put(R.id.nameText, 3);
    }
    // views
    @NonNull
    private final android.widget.LinearLayout mboundView0;
    // variables
    @Nullable
    private final android.view.View.OnClickListener mCallback1;
    // values
    // listeners
    // Inverse Binding Event Handlers

    public ActivityMainBindingImpl(@Nullable androidx.databinding.DataBindingComponent bindingComponent, @NonNull View root) {
        this(bindingComponent, root, mapBindings(bindingComponent, root, 4, sIncludes, sViewsWithIds));
    }
    private ActivityMainBindingImpl(androidx.databinding.DataBindingComponent bindingComponent, View root, Object[] bindings) {
        super(bindingComponent, root, 0
            , (android.widget.Button) bindings[1]
            , (android.widget.EditText) bindings[2]
            , (android.widget.TextView) bindings[3]
            );
        this.inputButton.setTag(null);
        this.mboundView0 = (android.widget.LinearLayout) bindings[0];
        this.mboundView0.setTag(null);
        setRootTag(root);
        // listeners
        mCallback1 = new com.psw.mylivedata.generated.callback.OnClickListener(this, 1);
        invalidateAll();
    }

    @Override
    public void invalidateAll() {
        synchronized(this) {
                mDirtyFlags = 0x2L;
        }
        requestRebind();
    }

    @Override
    public boolean hasPendingBindings() {
        synchronized(this) {
            if (mDirtyFlags != 0) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean setVariable(int variableId, @Nullable Object variable)  {
        boolean variableSet = true;
        if (BR.mymain == variableId) {
            setMymain((com.psw.mylivedata.NameViewModel) variable);
        }
        else {
            variableSet = false;
        }
            return variableSet;
    }

    public void setMymain(@Nullable com.psw.mylivedata.NameViewModel Mymain) {
        this.mMymain = Mymain;
        synchronized(this) {
            mDirtyFlags |= 0x1L;
        }
        notifyPropertyChanged(BR.mymain);
        super.requestRebind();
    }

    @Override
    protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
        switch (localFieldId) {
        }
        return false;
    }

    @Override
    protected void executeBindings() {
        long dirtyFlags = 0;
        synchronized(this) {
            dirtyFlags = mDirtyFlags;
            mDirtyFlags = 0;
        }
        com.psw.mylivedata.NameViewModel mymain = mMymain;
        // batch finished
        if ((dirtyFlags & 0x2L) != 0) {
            // api target 1

            this.inputButton.setOnClickListener(mCallback1);
        }
    }
    // Listener Stub Implementations
    // callback impls
    public final void _internalCallbackOnClick(int sourceId , android.view.View callbackArg_0) {
        // localize variables for thread safety
        // mymain != null
        boolean mymainJavaLangObjectNull = false;
        // mymain
        com.psw.mylivedata.NameViewModel mymain = mMymain;



        mymainJavaLangObjectNull = (mymain) != (null);
        if (mymainJavaLangObjectNull) {


            if ((nameInput) != (null)) {


                nameInput.getText();
                if ((nameInput.getText()) != (null)) {


                    nameInput.getText().toString();

                    mymain.btnClick(nameInput.getText().toString());
                }
            }
        }
    }
    // dirty flag
    private  long mDirtyFlags = 0xffffffffffffffffL;
    /* flag mapping
        flag 0 (0x1L): mymain
        flag 1 (0x2L): null
    flag mapping end*/
    //end
}

 

어떻게 해결해야 하나요??

개미1 (1,260 포인트) 님이 2022년 10월 4일 질문
개미1님이 2022년 10월 4일 수정

1개의 답변

0 추천
Databinding은 사용방법이 약간 다를 겁니다. 지금 사용하신 코드는 데이터바인딩을 사용하지 않을 때 사용하는 방법입니다. 데이터바인딩은 데이터 바인딩 사용법을 공부하셔야 해요. 데이터바인딩은 nameObserver같은 코드가 필요없고 대신에 XML에 직접 LiveData를 바인딩해주시는 형태로 사용합니다. 제가 데이터바인딩을 사용하지 않는 관계로 링크를 남겨놓을게요. 조금만 읽어보시면 어떻게 사용하는지 감이 오실 겁니다.

https://developer.android.com/topic/libraries/data-binding
spark (226,420 포인트) 님이 2022년 10월 4일 답변
혹시 빌드에러일 수도 있으니 Clean build, Invalidate cache and restart도 시도해 보세요.
...