简体   繁体   English

在Android中每秒更新

[英]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. 我是android的新手,因此我对onCreate方法总体上不太清楚。 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. 我认为它由于t.start()行而崩溃,但我不知道如何触发该事件。

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);
    }
}

One problem was a NumberFormatException when trying to parse a Double as an Integer. 一个问题是试图解析Double作为整数时出现NumberFormatException。

The other problem was trying to call setText() with an int on this line: 另一个问题是尝试在此行上使用int调用setText()

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!). 首先,将Thread t为实例变量,以便可以在按钮click run()方法中对其进行访问(您可能也想重命名该方法!)。

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: 编辑2:

As @BladeCoder mentioned in the comments, a Thread is really over-kill for this. 正如@BladeCoder在评论中提到的那样,Thread实在是太过分了。 Using a Handler and postDelayed() is really the best route for something like this. 使用Handler和postDelayed()实际上是实现此类目标的最佳途径。

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. 另外,最好将TextView设置为实例变量,这样就不必在每次更新时都创建新的引用。

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));
    }

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

Instead of using thread to achieve this, you can achieve the same effect with a "neat way" using the Timer class. 除了使用线程来实现此目的外,还可以使用Timer类以“巧妙的方式”实现相同的效果。

Check this stackoverflow answer Android timer? 检查这个stackoverflow答案Android计时器吗? How-to? 如何?

Regarding the onCreate method I suggest you to check the activity life cycle 关于onCreate方法,我建议您检查活动生命周期

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(). 始终跟在on​​Start()之后。

Check the documentation for further info http://developer.android.com/reference/android/app/Activity.html#onCreate(android.os.Bundle) 检查文档以获取更多信息http://developer.android.com/reference/android/app/Activity.html#onCreate(android.os.Bundle)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM