Note that there are some explanatory texts on larger screens.

plurals
  1. POchangeCursor causes CalledFromWrongThreadException exception... but only once
    primarykey
    data
    text
    <p>I'm working with a listview and a context menu. When the user long presses an item in the context menu, a little mark appears next to the item in the list, to let the user know the item has been marked a favorite. This is all working well, EXCEPT that it causes a force close the very first time this is done. Every other time works just fine. Here is the relevant code:</p> <pre><code> @Override public boolean onContextItemSelected(MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); switch (item.getItemId()) { case 0: mDbHelper.updateFavorite(info.id, 1); new bgRequery().execute(); return true; case 1: mDbHelper.updateFavorite(info.id, 0); new bgRequery().execute(); return true; default: return super.onContextItemSelected(item); } } private class bgRequery extends AsyncTask&lt;Void, Integer, Void&gt; { @Override protected Void doInBackground(Void... voids ) { mSpellCursor = fetchCursor(); return null; } @Override protected void onPostExecute(Void voids) { spellsAdapter.changeCursor(mSpellCursor); } } </code></pre> <p>Here is the exception:</p> <blockquote> <p>D/SpellBook( 5362): fetching Cursor E/AndroidRuntime( 5362): FATAL EXCEPTION: background thread E/AndroidRuntime( 5362): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. E/AndroidRuntime( 5362): at android.view.ViewRoot.checkThread(ViewRoot.java:2932) E/AndroidRuntime( 5362): at android.view.ViewRoot.requestLayout(ViewRoot.java:629) E/AndroidRuntime( 5362): at android.view.View.requestLayout(View.java:8267) E/AndroidRuntime( 5362): at android.view.View.requestLayout(View.java:8267) E/AndroidRuntime( 5362): at android.view.View.requestLayout(View.java:8267) E/AndroidRuntime( 5362): at android.view.View.requestLayout(View.java:8267) E/AndroidRuntime( 5362): at android.widget.AbsListView.requestLayout(AbsListView.java:1102) E/AndroidRuntime( 5362): at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:790) E/AndroidRuntime( 5362): at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:31) E/AndroidRuntime( 5362): at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50) E/AndroidRuntime( 5362): at android.widget.CursorAdapter.changeCursor(CursorAdapter.java:260) E/AndroidRuntime( 5362): at com.zalzala.spellbookpf.SpellsAz$bgRequery.onPostExecute(SpellsAz.java:228) E/AndroidRuntime( 5362): at com.zalzala.spellbookpf.SpellsAz$bgRequery.onPostExecute(SpellsAz.java:1) E/AndroidRuntime( 5362): at android.os.AsyncTask.finish(AsyncTask.java:417)</p> </blockquote> <p>So the error occurs when spellsAdapter.changeCursor(mSpellCursor); is called in onPostExecute. Since that function runs in the ui thread, I'm having a hard time understanding why I'm getting a background Tread error. What's making this harder to understand and debug is that it really only happens the very first time I do this. Every other time it works fine, even when the app starts fresh or the phone has rebooted. The only way to reproduce the bug is to uninstall the app and install it fresh. </p> <p>Just in case anyone needs it, I'm including the code of my adapter:</p> <pre><code>public class SpellListAdapter extends CursorAdapter { private LayoutInflater mLayoutInflater; private Context mContext; public SpellListAdapter(Context context, Cursor c) { super(context, c); mContext = context; mLayoutInflater = LayoutInflater.from(context); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { View v = mLayoutInflater.inflate(R.layout.list_item_fave, parent, false); return v; } @Override public void bindView(View v, Context context, Cursor c) { String spell = c.getString(c.getColumnIndexOrThrow(SpellDbAdapter.KEY_SPELL)); int fave = c.getInt(c.getColumnIndexOrThrow(SpellDbAdapter.KEY_FAVORITE)); /** * Next set the title of the entry. */ TextView Spell = (TextView) v.findViewById(R.id.text); if (Spell != null) { Spell.setText(spell); } //Set Fave Icon TextView Fave = (TextView) v.findViewById(R.id.fave_icon); Fave.setVisibility(View.INVISIBLE); if (fave == 1){ Fave.setVisibility(View.VISIBLE); } } public void update() { notifyDataSetChanged(); } } </code></pre> <p>Thanks for your help.</p> <p><strong>EDIT:</strong> I can work around this issue by not calling the cursor in a separate thread, but I thought it was good practice to use another thread for it instead of using the ui thread, so I would still love some help figuring this out.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload