나는 listview 및 컨텍스트 메뉴로 작업하고 있습니다. 사용자가 컨텍스트 메뉴에서 항목을 길게 누르면 목록에 항목 옆에 작은 기호가 나타나 항목이 즐겨 찾기로 표시되었음을 알립니다. 이 작업이 처음 수행 될 때 강제 종료가 발생하는 것을 제외하고는 모두 잘 작동합니다. 다른 모든 시간은 잘 작동합니다. (5362)changeCursor는 CalledFromWrongThreadException 예외를 발생시킵니다. 단 한 번만
D/마법서 : 여기서
예외이다 여기 관련 코드 커서 페치 E/AndroidRuntime (5362) FATAL EXCEPTION : 배경 스레드 E/AndroidRuntime (5362) : android.view.ViewRoot $ CalledFromWrongThreadException : 뷰 계층을 으로 만든 원래 스레드 만 해당 뷰를 터치 할 수 있습니다. E/AndroidRuntime (5362) android.view.ViewRoot.checkThread (ViewRoot.java:2932) (5362) E/AndroidRuntime에서 : android.view.ViewRoot.requestLayout (ViewRoot.java:629)에서 E /AndroidRuntime (5362) android.view.View.requestLayout (View.java:8267)에서 E/AndroidRuntime : android.view.View.requestLayout (View.java:8267) (5362) E/AndroidRuntime에서 (5362) : android.view.View.requestLayout (View.java:8267) E/AndroidRuntime (5362) : 에서 android.view.View.requestLayout (View.java:8267) E/AndroidRuntime (5362)) : at android.widget.AbsListView.requestLayout (AbsListView.ja) 버지니아 : 1102) E/AndroidRuntime (5362) : android.widget.AdapterView $ AdapterDataSetObserver.onChanged (AdapterView.java:790) (5362) E/AndroidRuntime에서 : android.database.DataSetObservable.notifyChanged (DataSetObservable에서. 자바 31) E/AndroidRuntime (5362)에서 android.widget.CursorAdapter.changeCursor (CursorAdapter.java : android.widget.BaseAdapter.notifyDataSetChanged (BaseAdapter.java:50) (5362) E/AndroidRuntime에서 : 260) E/AndroidRuntime (5362) : com.zalzala.spellbookpf.SpellsAz $ bgRequery.onPostExecute (SpellsAz.java:228) (5362) E/AndroidRuntime에서 : com.zalzala.spellbookpf.SpellsAz $ bgRequery에서. onPostExecute (SpellsAz.java) 1) E/AndroidRuntime (5362) android.os.AsyncTask.finish (AsyncTask.java:417)@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<Void, Integer, Void> { @Override protected Void doInBackground(Void... voids) { mSpellCursor = fetchCursor(); return null; } @Override protected void onPostExecute(Void voids) { spellsAdapter.changeCursor(mSpellCursor); } }
에서 그래서 에러가 발생할 때 spellsAdapter.changeCursor (mSpellCursor); onPostExecute에서 호출됩니다. 그 함수는 UI 스레드에서 실행되기 때문에 배경 트레드 오류가 발생하는 이유를 이해하는 데 어려움을 겪고 있습니다. 이 점을 이해하고 디버그하는 것이 더 어렵게 만드는 것은 이것이 내가 처음하는 순간에만 실제로 발생한다는 것입니다. 매번 앱을 새로 시작하거나 휴대 전화가 재부팅 된 경우에도 정상적으로 작동합니다. 버그를 재현하는 유일한 방법은 앱을 제거하고 새로 설치하는 것입니다. 당신의 도움에 대한
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();
}
}
감사 : 경우 사람이, 내 어댑터의 코드를 포함하고있어 그것을 필요로 그냥에서
.
편집 : 내가 별도의 스레드에서 커서를 호출하지 않음으로써이 문제를 해결할 수 있습니다,하지만 난 그것을 위해 다른 스레드를 사용하는 대신 UI 스레드를 사용하는 것이 좋다라고 생각, 그래서 난 아직도 사랑 일부는 이것을 알아내는 데 도움이됩니다.
처음으로 어떻게 목록을 채우는 지 비정상적인 점은 무엇입니까? – CommonsWare
나는 아무것도 생각할 수 없다. 매번 커서를 똑같은 방식으로 호출합니다. – anakin78z