问题描述
我正在制作一个基于薪资比率每秒计数的应用程序,按照现在的编写,它在启动时崩溃。
我在线程部分做错了吗?
我是android的新手,因此我对onCreate方法总体上不太清楚。 任何有关此内容及其与我的代码的关系的说明也将有所帮助。
该按钮应该开始计数。 我认为它由于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);
}
}
1楼
一个问题是试图解析Double作为整数时出现NumberFormatException。
另一个问题是尝试在此行上使用int调用setText()
:
text2.setText((int) update);
这修复了它:
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));
}
编辑:
这是您仅在单击按钮时启动线程的方法。
首先,将Thread t
为实例变量,以便可以在按钮click run()
方法中对其进行访问(您可能也想重命名该方法!)。
我刚刚测试了一下,它对我有用:
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));
}
//.........
编辑2:
正如@BladeCoder在评论中提到的那样,Thread实在是太过分了。 使用Handler和postDelayed()实际上是实现此类目标的最佳途径。
另外,最好将TextView设置为实例变量,这样就不必在每次更新时都创建新的引用。
我也测试了这个版本:
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));
}
//.............
2楼
除了使用线程来实现此目的外,还可以使用Timer类以“巧妙的方式”实现相同的效果。
检查这个stackoverflow答案
关于onCreate方法,我建议您检查活动生命周期
在第一次创建活动时调用。 在这里,您应该执行所有常规的静态设置:创建视图,将数据绑定到列表等。此方法还为您提供了一个包含活动先前冻结状态(如果存在)的捆绑包。 始终跟在on??Start()之后。
检查文档以获取更多信息