I need some help with an Android app I'm developing. I have tons of experience with C, perl, and assembly but I'm a complete Java noob.
In a nutshell, I'm writing an app that will display a running clock. I understand that there are built in clock widgets but I'd prefer to accomplish this with a TextView object that I update once per second. However, when I set up a repeating event and try to use the setText method, my app crashed. Something about calling setText from outside the thread that created it.
I searched a little and saw some suggestions about using handlers but I wasn't successful with that approach. Can someone point out what I'm doing wrong or suggest a better approach?
My code is below. I'm using Android Studio 0.8.9 and running the app on my LG G2.
Thanks in advance for any help you can provide.
package com.joshrocks.betclock;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.graphics.Typeface;
import android.widget.TextClock;
import android.widget.TextView;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
public class BET_Clock extends Activity {
//TextView and TextClock definitions
TextView lab_GMT;
TextView lab_LCL;
TextView lab_BET;
TextView lab_BJD;
TextView Day_LCL;
TextView Slash_LCL;
TextClock time_LCL;
TextView Day_GMT;
TextView Slash_GMT;
TextClock time_GMT;
//Calendar declarations
Calendar GMT_Calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
Calendar LCL_Calendar = Calendar.getInstance();
//Call GMT and LCL Day of the year
int GMT_dayOfYear = GMT_Calendar.get(Calendar.DAY_OF_YEAR);
int LCL_dayOfYear = LCL_Calendar.get(Calendar.DAY_OF_YEAR);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bet__clock);
Typeface dot_matrix=Typeface.createFromAsset(getAssets(),"fonts/led_counter-7.ttf");
//Label font definitions
lab_LCL = (TextView) findViewById(R.id.Label_LCL);
lab_LCL.setTypeface(dot_matrix);
lab_GMT = (TextView) findViewById(R.id.Label_GMT);
lab_GMT.setTypeface(dot_matrix);
lab_BET = (TextView) findViewById(R.id.Label_BET);
lab_BET.setTypeface(dot_matrix);
lab_BJD = (TextView) findViewById(R.id.Label_BJD);
lab_BJD.setTypeface(dot_matrix);
//GMT Time field font definitions
Day_GMT = (TextView) findViewById(R.id.Day_GMT);
Day_GMT.setTypeface(dot_matrix);
Day_GMT.setText(String.valueOf(GMT_dayOfYear));
Slash_GMT = (TextView) findViewById(R.id.Slash_GMT);
Slash_GMT.setTypeface(dot_matrix);
time_GMT = (TextClock) findViewById(R.id.Time_GMT);
time_GMT.setTypeface(dot_matrix);
//LCL Time field font definitions
Day_LCL = (TextView) findViewById(R.id.Day_LCL);
Day_LCL.setTypeface(dot_matrix);
Day_LCL.setText(String.valueOf(LCL_dayOfYear));
Slash_LCL = (TextView) findViewById(R.id.Slash_LCL);
Slash_LCL.setTypeface(dot_matrix);
time_LCL = (TextClock) findViewById(R.id.Time_LCL);
time_LCL.setTypeface(dot_matrix);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
UpdateTimes();
}
},0, 1000);
}//end OnCreate
public void UpdateTimes() {
LCL_dayOfYear += 1;
Day_LCL.setText(String.valueOf(LCL_dayOfYear));
}//end UpdateTimes
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.bet__clock, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Try this.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
UpdateTimes();
}
});
}
},0, 1000);
You need to call runOnUiThread in order to change view objects from other threads than the main UI thread.