Android app stopwatch

I am trying to develop a custom stopwatch application in android, but it throws the following exception:

android.view.ViewRoot $ CalledFromWrongThreadException: only the source thread that created the view hierarchy can touch its views.

I also tried to use the chronometer, but when we use the stop method, it starts from its previous value.

Below is the file of my activity

public class MainActivity extends Activity implements OnClickListener { TextView sec,milisec,min; Button start,stop,pause,resume; int count=0; Chronometer chrono; Timer timer; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); chrono=(Chronometer)findViewById(R.id.chronometer); milisec=(TextView)findViewById(R.id.milisec); sec=(TextView)findViewById(R.id.sec); min=(TextView)findViewById(R.id.min); start=(Button)findViewById(R.id.start); stop=(Button)findViewById(R.id.stop); pause=(Button)findViewById(R.id.pause); resume=(Button)findViewById(R.id.resume); System.out.println("-------1-------"); start.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //chrono.start(); //count=Integer.parseInt(count_view.getText().toString());*/ timer = new Timer(); timer.schedule(new TimerTask() { public void run() { System.out.println("-------2-------"); View v = new View(getApplicationContext()); count_increment(v); } },1000,10000); } }); stop.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //chrono.clearComposingText(); //chrono.setText("00"); timer.cancel(); } }); } public void count_increment(View v) { count++; System.out.println("count="+count); //count_str=String.valueOf(count); milisec.setText(""+count); } @Override public void onClick(View v) { // TODO Auto-generated method stub } } 

and the following xml file

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginTop="30dp" android:gravity="center_horizontal" > <TextView android:id="@+id/min" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="00" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=":" /> <TextView android:id="@+id/sec" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="00" /> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=":" /> <TextView android:id="@+id/milisec" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="00" /> </LinearLayout> <LinearLayout android:id="@+id/linearLayout1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginTop="60dp" android:gravity="center_horizontal" > <TableLayout android:layout_width="wrap_content" android:layout_height="match_parent" > <TableRow android:id="@+id/tableRow1" android:layout_width="wrap_content" android:layout_height="wrap_content" > <Button android:id="@+id/start" android:layout_width="80dp" android:layout_height="wrap_content" android:text="Start" /> <Button android:id="@+id/stop" android:layout_width="80dp" android:layout_height="wrap_content" android:text="Stop" /> <Button android:id="@+id/pause" android:layout_width="80dp" android:layout_height="wrap_content" android:text="Pause" /> <Button android:id="@+id/resume" android:layout_width="80dp" android:layout_height="wrap_content" android:text="Resume" /> </TableRow> <TableRow android:id="@+id/tableRow1" android:layout_width="wrap_content" android:layout_height="wrap_content" > <Chronometer android:id="@+id/chronometer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Chronometer" /> </TableRow> </TableLayout> </LinearLayout> </RelativeLayout> 

What is going wrong? Is there any other way to create a stopwatch?

+4
source share
2 answers

The error message is fully explained: you should not touch the user interface element directly in the new thread. A possible workaround is that you send the executable to the user interface stream to update the user interface using Activity.runOnUiThread ()

I mean something like this (pseudocode has not been tested):

 public void count_increment(View v) { count++; System.out.println("count="+count); //count_str=String.valueOf(count); // milisec.setText(""+count); final String str = ""+count; runOnUiThread(new Runnable() { public void run() { milisec.setText(str); } }); } 
+1
source

you cannot change view / setText from a child stream. Access to the view can only be obtained from the user interface / main thread.

try this from inside the child thread

  runOnUiThread(new Runnable() { @Override public void run() { count_increment(v); } }); 
+1
source

Source: https://habr.com/ru/post/1441184/


All Articles