Terik Brunson
Terik Brunson

Reputation: 187

Updating each second in Android

I am making an app that counts up every second based on rate of pay, and as it is written now, it crashes on startup.

Am I doing the thread section wrong?

I am kind of new to android, so I am a bit unclear on the onCreate method in general. Any clarification about that and how it relates to my code would be helpful as well.

The button is supposed to start the count. I think it's crashing due to the t.start() line, but I don't know how to trigger the event.

package com.example.terik.myapplication;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;


public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView text2;
        text2 = (TextView) findViewById(R.id.textView2);

        Thread t = new Thread() {

            @Override
            public void run() {
                try {
                    while (!isInterrupted()) {
                        Thread.sleep(1000);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                updateTextView();
                            }
                        });
                    }
                } catch (InterruptedException e) {
                }
            }
        };

        t.start();
    }

    private void updateTextView() {
        TextView text2;
        double update;
        double rateofPay = 9.00;
        text2 = (TextView)findViewById(R.id.textView2);
       CharSequence newtime = text2.getText();
        int number = Integer.parseInt(newtime.toString());
        update = number+ rateofPay;
        text2.setText((int) update);

    }




    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, 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();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Upvotes: 1

Views: 91

Answers (2)

Daniel Nugent
Daniel Nugent

Reputation: 43322

One problem was a NumberFormatException when trying to parse a Double as an Integer.

The other problem was trying to call setText() with an int on this line:

text2.setText((int) update);

This fixed it:

private void updateTextView() {
    TextView text2;
    double update;
    double rateofPay = 9.00;
    text2 = (TextView)findViewById(R.id.textView2);
    CharSequence newtime = text2.getText();
    double number = Double.parseDouble(newtime.toString());
    update = number+ rateofPay;
    text2.setText(String.valueOf(update));
}

Edit:

Here's how you would only start the Thread when you click the Button. First make the Thread t an instance variable, so that it can be accessed in the button click run() method (you might want to re-name that method too!).

I just tested this, it worked for me:

public class MainActivity extends ActionBarActivity {

    Thread t;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView text2;
        text2 = (TextView) findViewById(R.id.textView2);

        t = new Thread() {

            @Override
            public void run() {
                try {
                    while (!isInterrupted()) {
                        Thread.sleep(1000);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                updateTextView();
                            }
                        });
                    }
                } catch (InterruptedException e) {
                }
            }
        };

    }

    public void run(View v) {
        t.start();
    }

    private void updateTextView() {
        TextView text2;
        double update;
        double rateofPay = 9.00;
        text2 = (TextView)findViewById(R.id.textView2);
        CharSequence newtime = text2.getText();
        double number = Double.parseDouble(newtime.toString());
        update = number+ rateofPay;
        text2.setText(String.valueOf(update));
    }

    //.........

Edit 2:

As @BladeCoder mentioned in the comments, a Thread is really over-kill for this. Using a Handler and postDelayed() is really the best route for something like this.

Also, it would be better to make the TextView an instance variable so that you don't create a new reference every time you update it.

I tested this version as well:

public class MainActivity extends ActionBarActivity {

    TextView text2;
    Handler handler;

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

        text2 = (TextView) findViewById(R.id.textView2);

        handler = new Handler();

    }

    Runnable updateText = new Runnable(){
        @Override
        public void run(){
            updateTextView();
            handler.postDelayed(this, 1000);
        }
    };

    public void run(View v) {
        handler.postDelayed(updateText, 1000);
    }

    private void updateTextView() {

        double update;
        double rateofPay = 9.00;
        CharSequence newtime = text2.getText();
        double number = Double.parseDouble(newtime.toString());
        update = number+ rateofPay;
        text2.setText(String.valueOf(update));
    }

    //.............

Upvotes: 2

msamhoury
msamhoury

Reputation: 331

Instead of using thread to achieve this, you can achieve the same effect with a "neat way" using the Timer class.

Check this stackoverflow answer Android timer? How-to?

Regarding the onCreate method I suggest you to check the activity life cycle

Called when the activity is first created. This is where you should do all of your normal static set up: create views, bind data to lists, etc. This method also provides you with a Bundle containing the activity's previously frozen state, if there was one. Always followed by onStart().

Check the documentation for further info http://developer.android.com/reference/android/app/Activity.html#onCreate(android.os.Bundle)

Upvotes: 0

Related Questions