KaliMa KaliMa - 7 months ago 70
Java Question

Sqlite error: Only the original thread that created a view hierarchy can touch its views

I am trying to understand the cause of this error and how to fix it.

The error is

Only the original thread that created a view hierarchy can touch its views.
.

This is my code snippet.

public void refreshMyRecyclerView() {
new Thread(new Runnable(){
@Override
public void run(){
mValueList = mMyDatabase.fillValueList(); //pulls data from sqlite db
mRecyclerAdapter = new MyRecyclerAdapter(getActivity(), mValueList);
mRecyclerView.setAdapter(mRecyclerAdapter); //error on this line
}
}).start();

}


I am trying to follow good practice by performing SQLite reads inside its own thread, however I am encountering strange errors like the one above and I have no idea what's causing it even after reading similar questions involving the same error description.

Answer

You should only access UI components such as views from the UI thread. As you have found if you try to access them from a background thread you will get an error.

You can read the values from the database on the background thread but you should populate and set the adapter on the UI thread. If you are in an Activity you can use the method runOnUiThread(...). Otherwise if in a fragment getActivity().runOnUiThread(...) or mRecyclerView.post(...) will work too. All methods take a Runnable.

public void refreshMyRecyclerView() {
    new Thread(new Runnable(){
        @Override
        public void run(){
            mValueList = mMyDatabase.fillValueList(); //pulls data from sqlite db
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mRecyclerAdapter = new MyRecyclerAdapter(getActivity(), mValueList);
                    mRecyclerView.setAdapter(mRecyclerAdapter); //error on this line
                }
            });
        }
    }).start();
}