Adapter Android ListView nie zostanie odświeżony

Mam wiele problemów z odświeżeniem widoku listy za pomocą niestandardowego adaptera. Przeszukuję online przez ostatnią godzinę i nie mogę znaleźć żadnego rozwiązania, które sprawi, że widok listy zostanie odświeżony.

Próbowałem notifyDataSetChanged, a także listView.invalidate, ale nic nie działa. Każda pomoc byłaby bardzo mile widziana. Widzę, że dane są aktualizowane za pomocą logcat, ale nie są one odświeżane na ekranie i nie mam pojęcia dlaczego.

Poniżej znajduje się kod.

ArrayList<Student> students = new ArrayList<Student>();

listview = (ListView) findViewById(R.id.listView);
adapter = new StudentAdapter(this, R.layout.listitemlayout, students);  
listview.setAdapter(adapter);

Adapter niestandardowy

public class StudentAdapter extends ArrayAdapter<Student>{

    Context context; 
    int layoutResourceId;    
    ArrayList<Student> data = null;

    public StudentAdapter(Context context, int layoutResourceId, ArrayList<Student> data) {
        super(context, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = data;
    }

    public void updateStudentsList(ArrayList<Student> newlist){
        data.clear();
        data = newlist;
        this.notifyDataSetChanged();
    }

    public void updateStudentTime(){
        for (Student s : data) {
            s.updateElapsedTime();          
        }
        this.notifyDataSetChanged();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        if(row == null){
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            Student student = data.get(position);

            TextView title = (TextView)row.findViewById(R.id.txtTitle);
            title.setText(student.getFirstname() + " " + student.getLastname());

            TextView subTitle = (TextView)row.findViewById(R.id.txtSubTitle);
            subTitle.setText(student.getStudentID());       

            TextView duration = (TextView)row.findViewById(R.id.textDuration);
            duration.setText(student.getElapsedTime());
        }
        return row;
    }
}

Co jakiś czas aktualizuję dane za pomocą wątku.

Runnable runnable = new Runnable() {
            public void run() {
                runOnUiThread(new Runnable() {
                    public void run() {
                        // Updates how long the student is in the centre.
                        adapter.updateStudentTime();
                        adapter.notifyDataSetChanged();
                        listview.invalidate();
                        Log.i("Debug", "Running on UI Thread");
                    }
                });
                handler.postDelayed(this, 1000);
            }
        };
        handler.postDelayed(runnable, 1000);

questionAnswers(2)

yourAnswerToTheQuestion