首先感谢你的出色工作。论坛对我来说总是很好的帮助,但这次我需要问一个具体的问题。
我创建了一个类Tasks,它将在TextView
活动中每秒更新BatteryStatus
。我发现有两种方法可以更新文本:
对于解决方案1,我收到此错误:
09-30 20:08:29.635: W/System.err(14515): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
对于解决方案2,出现此错误:
09-30 21:23:07.110: W/System.err(16344): java.lang.NullPointerException
09-30 21:23:07.110: W/System.err(16344): at android.app.Activity.findViewById(Activity.java:1653)
好的,程序不知道TextView的位置和内容。 我需要更改什么才能使其正常工作? 我真的想要了解在另一个类中更新TextViews,Buttons ......的两种方法。
传递对Context接口的引用:
public class BatteryStatus extends Activity{
private static Timer myclock;
private static TimerTask mytask;
TextView tvBatteryStatus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_battery_status); // XML-Datei im Layout - Ordner
// Text View
tvBatteryStatus = (TextView) findViewById(R.id.tvBatteryStatus);
// Timer Task
myclock = new Timer();
mytask = new Tasks(BatteryStatus.this);
// schedule the task to run every 1000ms and delay execution for another 1000ms
myclock.scheduleAtFixedRate(mytask, 1000, 1000);
}
}
任务
public class Tasks extends TimerTask {
Context context;
public Tasks(Context context){this.context = context;}
public void run(){
try{Update();}
catch(Exception e){e.printStackTrace();}
}
public void Update(){
TextView txtView = (TextView) ((BatteryStatus)context).findViewById(R.id.tvBatteryStatus);
txtView.setText("Hello");
}
}
在活动类
带吸气剂的BatteryStatus
public class BatteryStatus extends Activity{
private static Timer myclock;
private static TimerTask mytask;
TextView tvBatteryStatus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_battery_status); // XML-Datei im Layout - Ordner
// Text View
tvBatteryStatus = (TextView) findViewById(R.id.tvBatteryStatus);
// Timer Task
myclock = new Timer();
mytask = new Tasks();
// schedule the task to run every 1000ms and delay execution for another 1000ms
myclock.scheduleAtFixedRate(mytask, 1000, 1000);
}
public TextView getTextView(){
TextView tV = (TextView)findViewById(R.id.tvBatteryStatus);
return tV;
}
}
任务
public class Tasks extends TimerTask {
TextView t;
BatteryStatus b = new BatteryStatus();
public void run(){
try{Update();}
catch(Exception e){e.printStackTrace();}
}
public void Update(){
t = b.getTextView();
t.setText("hellooo");
}
}
答案 0 :(得分:1)
快速而肮脏的解决方案:
编辑Tasks类:
public class Tasks extends TimerTask {
TextView t;
Activity activity;
BatteryStatus b = new BatteryStatus();
public void run(){
try{Update();}
catch(Exception e){e.printStackTrace();}
}
public void Update(){
if(activity != null){
activity.runOnUIThread(new Runnable(){
t = b.getTextView();
t.setText("hellooo");
});
}
}
public void setActivity(Activity a){ // this must be called from the rest of your application
activity = a;
}
}
答案 1 :(得分:1)
使用第二种方法,您将实例化一个新的Activity,而不是使用已初始化TextView的Activity。您必须在构造函数中提供活动的引用。
public Tasks(BatteryStatus b){this.b = b;}
你可以使用textView。
答案 2 :(得分:1)
android中的基本拇指规则是你只能在主线程上更新视图,因此你得到了异常
09-30 20:08:29.635: W/System.err(14515): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
它告诉您正在从非UI线程访问视图元素。因此,为了从非UI线程进行视图更改,请参阅此网站并阅读主题部分。它所需要的一切...... http://developer.android.com/guide/components/processes-and-threads.html
答案 3 :(得分:0)
针对您在第二个解决方案中遇到的问题在活动类中创建一个getter函数
您必须通过构造函数传递Context引用。
public class Tasks extends TimerTask {
TextView t;
BatteryStatus b = new BatteryStatus();
Context context;
public Tasks (Context context){
this.context=context;}
public void run(){
try{Update();}
catch(Exception e){e.printStackTrace();}
}
public void Update(){
TextView txtView = (TextView) ((Activity)context).findViewById(R.id.tvBatteryStatus);
txtView.setText("Hello");
}
}
并在此类中创建Tasks对象,并将此BatteryStatus活动的上下文传递给Tasks.class
public class BatteryStatus extends Activity{
private static Timer myclock;
private static TimerTask mytask;
TextView tvBatteryStatus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_battery_status); // XML-Datei im Layout - Ordner
// Text View
tvBatteryStatus = (TextView) findViewById(R.id.tvBatteryStatus);
// Timer Task
myclock = new Timer();
mytask = new Tasks();
// schedule the task to run every 1000ms and delay execution for another 1000ms
myclock.scheduleAtFixedRate(mytask, 1000, 1000);
// make an object and pass the reference of this activity
Tasks abc = new Tasks(BatteryStatus .this);
}
}