0

I have a fragment where I am using realm like this

String selectedLang;
Realm realm;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.user_profile, container, false);
        ButterKnife.bind(this, rootView);
        realm = Realm.getDefaultInstance();
        loginDatas = realm.where(LoginData.class).findFirst();
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            selectedLang = langList.get(position);
//tried this, still not working, added runOnUiThread and that also didn't work
/*Realm realGuys = Realm.getDefaultInstance();
                realGuys.executeTransactionAsync(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        loginDatas.getUser().setLanguage(selectedLang);
                        realm.insertOrUpdate(loginDatas);
                    }
                }, new Realm.Transaction.OnSuccess() {
                    @Override
                    public void onSuccess() {
                        FragmentTransaction ft = getFragmentManager().beginTransaction();
                        ft.detach(UserFragment.this).attach(UserFragment.this).commit();
                    }
                }, new Realm.Transaction.OnError() {
                    @Override
                    public void onError(Throwable error) {
                        error.printStackTrace();
                    }
                });*/
            realm.executeTransactionAsync(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
//getting the exception below here
                    loginDatas.getUser().setLanguage(selectedLang);
                    realm.insertOrUpdate(loginDatas);
                }
            }, new Realm.Transaction.OnSuccess() {
                @Override
                public void onSuccess() {
                    FragmentTransaction ft = getFragmentManager().beginTransaction();
                    ft.detach(UserFragment.this).attach(UserFragment.this).commit();
                }
            }, new Realm.Transaction.OnError() {
                @Override
                public void onError(Throwable error) {
                    error.printStackTrace();
                }
            });
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            selectedLang = langList.get(0);
        }
    });
}

First I take loginDatas from realm, then I have a spinner setup and in the onItemSelected, I need to set the value of the selected item to loginDatas and then set it to realm. I have setup my code like that and I am getting this exception

7:20.060 9708-9708/com.packagename W/System.err: java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.
        at io.realm.BaseRealm.checkIfValid(BaseRealm.java:426)
        at io.realm.LoginDataRealmProxy.realmGet$user(LoginDataRealmProxy.java:99)
        at com.comcast.comcastmobile.entity.LoginData.getUser(LoginData.java:22)
        at com.comcast.comcastmobile.user.UserFragment$2$1.execute(UserFragment.java:189)
        at io.realm.Realm$1.run(Realm.java:1502)
        at io.realm.internal.async.BgPriorityRunnable.run(BgPriorityRunnable.java:34)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)
theanilpaudel
  • 3,348
  • 8
  • 39
  • 67
  • Possible duplicate of [Realm access from incorrect thread](https://stackoverflow.com/questions/40344801/realm-access-from-incorrect-thread) – earthw0rmjim May 20 '18 at 08:54

1 Answers1

1

Kinda like how you cannot access UI thread views on a background thread, you also cannot access RealmObjects that you obtained on a different thread.

loginDatas was obtained from the UI thread Realm, so you cannot access it on the background thread that the async transaction is being executed on. You must find loginDatas from the background thread Realm to modify it on the background thread.

        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                LoginData loginDatas = realm.where(LoginData.class).findFirst();
                loginDatas.getUser().setLanguage(selectedLang);
               // realm.insertOrUpdate(loginDatas);
            }
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428