1

A ListView is loaded from a background thread that call get values from a SQLite database and load them into ArrayList. This thread to show results call a CustomHandler, but it don't receive messages from thread.

Here's a sample code :

HandlerThread thread;

public void myFunction(){
    thread = new HandlerThread("UIThread"){
        CustomHandler handler = new CustomHandler();
        public void run(){
            handler.sendEmptyMessage(0);
        }
    };
    thread.start();
}

private class CustomHandler extends Handler{
    public CustomHandler(){
        super();
    }

   @Override
    public void handleMessage(Message msg){
        Log.i("Test","Test");
    }
}

I don't understand why my handler don't show text inside Log.i()

Here my complete code :

PART 1 :

private void caricaSintomi(){
    Log.i(Strumenti.NOMEAPP, "Inizio caricamento dei sintomi");
    HandlerThread thSintomi = new HandlerThread("UIThread"){
        private ArrayList<Sintomo> array;
        private CaricaSintomiHandler caricaSintomihandler;

        public void run(){
            Log.i(Strumenti.NOMEAPP, "Caricamento dei sintomi...");
            array = new ArrayList<Sintomo>();
            HashMap<String, ArrayList<String>> tabella = MainActivity.db.getTabella(TABELLA);   
            for(int j=0;j<tabella.get("Sintomi_malattie").size();j++){
                Sintomo sintomo = new Sintomo(Integer.parseInt(tabella.get("_id").get(j)),
                        tabella.get("Sintomi_malattie").get(j));
                array.add(sintomo);
            }
            Log.i(" ", "a "+array.get(0).getTesto());
            This.getLooper();
            caricaSintomihandler = new CaricaSintomiHandler(getThis(), array); //getThis is a class method that return the class itself (SintomiActivity.java)
            caricaSintomihandler.sendEmptyMessage(0); //Invio del messaggio per aggiornare la ListView
            Log.i(Strumenti.NOMEAPP, "Caricamento avvenuto con successo");
        }
    };
    thSintomi.start();
}

PART 2 :

 private static class CaricaSintomiHandler extends Handler{

    private final WeakReference<SintomiActivity> mActivity;
    private ArrayList<Sintomo> array;

    public CaricaSintomiHandler(SintomiActivity activity, ArrayList<Sintomo> array){
        super();
        this.mActivity = new WeakReference<SintomiActivity>(activity);
        this.array = array;
    }

    @Override
    public void handleMessage(Message msg){
        final SintomiActivity activity = mActivity.get();
        Log.i(" ","b "+ array.get(0).getTesto());
        activity.runOnUiThread(new Runnable() {
            public void run() {
                Log.i(" ","c "+ array.get(0).getTesto());
                for(int i=0; i < array.size(); i++){
                    activity.arraySintomi.add(array.get(i));
                }
                activity.visualizzaSintomi();
            }
        });
    }
}

I can't show my listView if Handler don't receive messages.


I found solution by editing code such this :

private void caricaSintomi(){
    Log.i(Strumenti.NOMEAPP, "Inizio caricamento dei sintomi");
    HandlerThread thSintomi = new HandlerThread("UIThread"){
        private ArrayList<Sintomo> array;
        private CaricaSintomiHandler handler = new CaricaSintomiHandler(){
            @Override
            public void handleMessage(Message msg){
                Log.i(" ","b "+ array.get(0).getTesto());
                runOnUiThread(new Runnable() {
                    public void run() {
                        Log.i(" ","c "+ array.get(0).getTesto());
                        for(int i=0; i < array.size(); i++){
                            arraySintomi.add(array.get(i));
                        }
                        visualizzaSintomi();
                    }
                });
            }
        };

        public void run(){
            CursorAdapter ca = new CursorAdapter(getApplicationContext(), null) {

                @Override
                public View newView(Context arg0, Cursor arg1, ViewGroup arg2) {
                    // TODO Auto-generated method stub
                    return null;
                }

                @Override
                public void bindView(View arg0, Context arg1, Cursor arg2) {
                    // TODO Auto-generated method stub

                }
            };

            Log.i(Strumenti.NOMEAPP, "Caricamento dei sintomi...");
            array = new ArrayList<Sintomo>();
            /*
             * Vengono caricati tutti i farmaci riga per riga.
             */
            HashMap<String, ArrayList<String>> tabella = MainActivity.db.getTabella(TABELLA);   
            //Invio query per ottenere un intervallo di tabella
            //Inserimento dei risultati all'interno di @array
            for(int j=0;j<tabella.get("Sintomi_malattie").size();j++){
                Sintomo sintomo = new Sintomo(Integer.parseInt(tabella.get("_id").get(j)),
                        tabella.get("Sintomi_malattie").get(j));
                array.add(sintomo);
            }
            Log.i(" ", "a "+array.get(0).getTesto());
            handler.sendEmptyMessage(0); //Invio del messaggio per aggiornare la ListView
            Log.i(Strumenti.NOMEAPP, "Caricamento avvenuto con successo");
        }
    };
    thSintomi.start();
}


private static class CaricaSintomiHandler extends Handler{

    public CaricaSintomiHandler(){
        super();
    }
}

I implement handleMessage(Message msg) into the handler creation by overriding it. On pskink suggestion, now i'm rewriting my code by using CursorAdapter class.

raythurnevoid
  • 2,652
  • 1
  • 25
  • 24

1 Answers1

0

As I remember, you cant create a handler inside a thread that has not called Looper.prepare(). Try to put in you run() method these two lines at the top

Looper.myLooper();
Looper.prepare();
Semyon Danilov
  • 1,753
  • 1
  • 17
  • 37