Assurez-vous que le contenu de votre carte n'est pas modifié à partir d'un thread d'arrière-plan, mais seulement à partir de la thread de l'INTERFACE utilisateur

J'ai une Activité avec un EditText (nommé "filtro") et un ListView (nommé "list_view").
Lorsque l'utilisateur insère le texte, l'adaptateur doit être d'actualisation;
si je change le texte plusieurs fois, vient un crash suivi par le message "vérifiez le contenu de votre carte n'est pas modifié à partir d'un thread d'arrière-plan, mais seulement à partir de la thread de l'INTERFACE utilisateur"

auditeur
:

    filtro.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {

            Log.d(TAG, "onTextChanged(" + cs + ")");
            adapter.getFilter().filter(cs); 
        }
        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
        }           
        @Override
        public void afterTextChanged(Editable arg0) {
        }
    });     
}

adaptateur:

public class ArticoliAdapter s'étend BaseAdapter implémente Filtrables {
[...]

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    [...]
}

@Override
public Filter getFilter() {

    if(mFilter == null)
        mFilter = new CustomFilter();
    return mFilter;
}




private class CustomFilter extends Filter {


    @Override
    protected FilterResults performFiltering(CharSequence constraint) {

        FilterResults results = new FilterResults();

        if (index == null) {
            synchronized (mLock) {
                index = new ArrayList<Long>();
            }
        } 
        else {
            index.clear();
        }


        [...some controls...] 

            if(flag_controls) {                     
                index.add(new Long(i));
                categoria_vuota = false;
                continue;
            }
        }

        filtered = true;

        synchronized (mLock) {
            results.values = index;
            results.count = index.size();
        }            
        return results;            
    }


    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {

        notifyDataSetChanged();

        if (results.count == 0)
            notifyDataSetInvalidated();
        else {
            index = (ArrayList<Long>) results.values;
            notifyDataSetChanged();
        }
    }
} 

ErrorLog:

12-03 16:53:26.527: D/AndroidRuntime(15434): Shutting down VM
12-03 16:53:26.527: W/dalvikvm(15434): threadid=1: thread exiting with uncaught exception (group=0x416052a0)
12-03 16:53:26.543: E/AndroidRuntime(15434): FATAL EXCEPTION: main
12-03 16:53:26.543: E/AndroidRuntime(15434): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131230967, class android.widget.ListView) with Adapter(class it.losi.ordcliagent.ArticoliAdapter)]
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.widget.ListView.layoutChildren(ListView.java:1538)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.widget.AbsListView.onLayout(AbsListView.java:2300)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.View.layout(View.java:14061)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.ViewGroup.layout(ViewGroup.java:4374)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1655)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1513)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.widget.LinearLayout.onLayout(LinearLayout.java:1426)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.View.layout(View.java:14061)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.ViewGroup.layout(ViewGroup.java:4374)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.View.layout(View.java:14061)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.ViewGroup.layout(ViewGroup.java:4374)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1655)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1513)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.widget.LinearLayout.onLayout(LinearLayout.java:1426)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.View.layout(View.java:14061)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.ViewGroup.layout(ViewGroup.java:4374)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.View.layout(View.java:14061)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.ViewGroup.layout(ViewGroup.java:4374)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1986)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1807)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4464)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.Choreographer.doCallbacks(Choreographer.java:555)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.Choreographer.doFrame(Choreographer.java:525)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.os.Handler.handleCallback(Handler.java:615)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.os.Handler.dispatchMessage(Handler.java:92)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.os.Looper.loop(Looper.java:137)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at android.app.ActivityThread.main(ActivityThread.java:4895)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at java.lang.reflect.Method.invokeNative(Native Method)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at java.lang.reflect.Method.invoke(Method.java:511)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
12-03 16:53:26.543: E/AndroidRuntime(15434):    at dalvik.system.NativeStart.main(Native Method)

SOLUTION
Avec le contrôle si(Looper.myLooper() == Looper.getMainLooper ()), j'ai compris que la méthode performFiltering() de générer automatiquement un nouveau thread.

J'ai créé une nouvelle méthode appelée "filtra()" pour forcer le code pour utiliser le MainTread:

public class CustomFilter extends Filter {
public void filtra(final CharSequence constraint) {
activity.runOnUiThread(new Runnable() {
public void run() {
publishResults(constraint, eseguiAggiornamento(constraint));
}});
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
return eseguiAggiornamento(constraint);         
}
private FilterResults eseguiAggiornamento(CharSequence constraint) {
[...code...]
}

}

doen pas l'air mal et je ne vois pas de thread d'arrière-plan. Pourriez-vous ajouter le plein de fermeture inopinée à votre question?
Fait.. avez-vous une idée?
L'erreur dit en gros: il y a eu un changement de données, mais aucun notifyDataSetChanged() (qui ListViews reçoivent de leur Carte). Aucune idée d'où / pourquoi. Est-il un thread / asynctask / .. impliqué dans la mise à jour des données dans la carte?
Rien de discussions.. Lorsque je modifie le texte dans l'EditText, je pense que l'UiThread (ou thread principal) essayez de modifier la liste (ce que je veux).. Mais si je insérer un grand nombre de caractères, l'UiThread ne disposez pas de beaucoup de temps pour mettre fin à la dernière mise à jour. Il existe une méthode pour dire "attend la fin de la dernière mise à jour" ?
Scusa potrei chiederti venir hai risolto? Ho visto che sei italiano :), perchè sono capitato dans una situazione similé. Ho una AutocompleteTextView con un Adaptateur<T> personalizzato che mise en oeuvre de l'interfaccia Filtrables. Quando la lista sulla quale filtro è abbastanza grande (5000 elementi), l'app crasha con la se stessa eccezione che hai avuto tu. Quel metodo filtra(Charsequence contrainte) che esegue l'aggiornamento sul Thread d'INTERFACE utilisateur colombe lo chiami? Scusa e grazie!

OriginalL'auteur Tirrel | 2013-12-03