I am trying to develop a custom stop watch application in android but it throw following exception:
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
I have also tried to use chronometer but when we use it’s stop method it starts from its previous value.
following is my activity file
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 following is 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 than this to develop stopwatch?
The error message is quite self-explained: you shall not touch the UI element directly in a new thread. A possible workaround is that you post a runnable to the UI thread to update the UI by Activity.runOnUiThread()
I mean something like this (pseudo code not tested):