0

I'm new to Android development and I was needed to quickly develop simple app. I need to dynamically generate list of views and and use timer in each of them, so my current code looks like this:

public class MainActivity extends AppCompatActivity {
    private List<TextView> times = new ArrayList<>();
    private Handler handler;

    private void initWatchlist() {
        LinearLayout line = new LinearLayout(this);
        line.setOrientation(LinearLayout.HORIZONTAL);

        TextView time = new TextView(this);
        time.setText(sdf.format(new Date()));
        time.setTextSize(32);
        line.addView(time);
        times.add(time);

        //add couple of other views to line
        //...

        LinearLayout watchlist = findViewById(R.id.watchlist);
        watchlist.addView(line);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initWatchlist();

        Thread thread = new Thread(){
            private Calendar previousDate = Calendar.getInstance();
            public void run(){
                if (previousDate.get(Calendar.MINUTE) != Calendar.getInstance().get(Calendar.MINUTE)) {
                    for (TextView textView : times) {
                        textView.setText(sdf.format(new Date()));
                    }
                }
            }
        };

        handler = new Handler();
        handler.post(thread);
    }

    //other code
}

So the problem is that it seems like my Thread doesn't do anything actually. I don't see my textviews update time. What am I doing wrong?

Android
  • 1,420
  • 4
  • 13
  • 23
shaurun
  • 70
  • 6
  • Calendar.getInstance() gets a default calendar with the actual date at the time it is requested, the android.os.Handler starts the thread with a few milliseconds of difference from its post call, so the if condition on the Thread will almost always evaluate to false. – Tassadar Feb 19 '19 at 23:07
  • I've modified the code to remove any dependency on Calendar and it still doesn't help. – shaurun Feb 19 '19 at 23:33

2 Answers2

1

To update UI you need to run your code on the main thread. One way to do this is to create a Handler that uses the MainLooper as seen below

Handler mainHandler = new Handler(Looper.getMainLooper());

Since you are in your Activity you can also use runOnUIThread();

Nelson Hoang
  • 413
  • 2
  • 11
  • Thanks for the answer, I've tried that, but It actually seems that my thread doesn't run at all. I've tried to add couple of breakpoints and simple System.out.println() statements, removed if - no reactions from anywhere, and no result with getMainLooper also. – shaurun Feb 19 '19 at 23:36
  • Make sure you define LayoutParams for your TextView (https://stackoverflow.com/questions/4203506/how-to-add-a-textview-to-a-linearlayout-dynamically-in-android). When you debug is your ArrayList of TextView populated? How long can your list be? A simpler way to accomplish this would be to add a RecylerView(https://developer.android.com/guide/topics/ui/layout/recyclerview) to your LinearLayout in XML and define an adapter to populate an arbitrary number of TextViews. Because currently you are nesting two LinearLayouts when that is not necessary. – Nelson Hoang Feb 19 '19 at 23:46
0

I'm stupid. My thread was actually finished pretty fast because it didn't contained while(true) {} or something;

The issue was solved by adding extra handler.postDelayed(thread, 1000) into my thread.run() function.

shaurun
  • 70
  • 6