我一直在阅读我的java书中的线程,我想尝试同时使用两个连续的线程进行更新。
当然虽然线程无法更新UI。我稍微使用过处理程序,但只是将信使从一个类传递到另一个类以捕获从服务到活动的位置。
但这必须比那更简单。
我假设我应该使用AsyncTask但我想在每个字段中计算1-10,并且我不想继续浸入和退出asynctask类。
赞赏任何指针
斯蒂芬
更新
所以我做了一些实验。我编写了一个处理程序方法来处理发送给它的任何消息。它检查它应该更新哪个字段,然后在所述字段上执行setText。这是代码
Handler myHandler = new Handler(){
public void handleMessage(Message msg){
msg = Message.obtain();
Bundle bundle = msg.getData();
String fieldName = bundle.getString("fieldName");
int count = bundle.getInt("count");
if(fieldName=="text1"){
text1.setText(count);
}else{
text2.setText(count);
}
}
};
然后我在我的活动的onCreate中有一些代码启动了两个线程,每个线程将带有我的int计数的消息传递给处理程序。它还传入一个TextView名称,以便我的处理程序知道它应该更新哪个textview。这是代码......
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text1 = (TextView)findViewById(R.id.text1);
text2 = (TextView)findViewById(R.id.text2);
new Thread(){
public void run(){
for(int i=1;i<10;i++){
message = Message.obtain(myHandler);
Bundle bundle = new Bundle();
bundle.putCharSequence("fieldName", "text1");
message.setData(bundle);
myHandler.sendMessageDelayed(message, 1000);
}
}
}.start();
new Thread(){
public void run(){
for(int i=1;i<10;i++){
message = Message.obtain(myHandler);
Bundle bundle = new Bundle();
bundle.putCharSequence("fieldName", "text2");
message.setData(bundle);
myHandler.sendMessageDelayed(message, 1000);
}
}
}.start();
}
但是我在setText上收到错误
05-17 17:13:00.013:ERROR / AndroidRuntime(966):android.content.res.Resources $ NotFoundException:String resource ID#0x0
有什么想法吗?
答案 0 :(得分:1)
这是你能做的。您正在使用AsyncTask的正确轨道,因此扩展该类并将您的计数放入进度更新功能。你应该有这样的东西:
private class BackgroundTask extends AsyncTask<Void, Void, Void> {
int i;
protected void onPreExecute() {
i = 0;
}
@Override
protected Void doInBackground(Void... arg0) {
i++;
publishProgress(i);
}
protected void onProgressUpdate(Integer... progress) {
TextView tv1 = (TextView) Main.this.findViewById(R.id.textView1)
TextView tv2 = (TextView) Main.this.findViewById(R.id.textView2)
tv1.setText(i);
tv2.setText(i);
}
protected void onPostExecute(Void result) {
i = null;
}
}
其中Main
是您的活动,textView1
和textView2
是您要更新的文字视图。
答案 1 :(得分:1)
如果你真的想运行两个额外的线程,可以使用处理程序完成。只需为您的活动创建一个处理程序并切换到什么。然后启动两个线程,当每个线程完成时,使用适当的值向处理程序发送消息。然后在处理程序中的UI线程中更新处理程序中的相应文本视图:
private Handler myHandler= new Handler(){
@Override
public void handleMessage(Message msg){
switch(msg.what){
case 0:
this.removeMessages(0);
Toast.makeText(Main.this,"Message0", Toast.LENGTH_SHORT).show();
break;
case 1:
this.removeMessages(1);
Toast.makeText(Main.this,"Message1", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
break;
}
}
};
只需使用您的UI更新代码替换吐司。您可以按以下方式启动线程:
// DISPLAY ON CLICK HANDLER
threadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Thread thread= new Thread( new Runnable() {
public void run() {
try { // DO NOT TOUCH THE UI HERE
Thread.sleep(1000); // mimic time consuming task
}
catch(Exception e){
}
myHandler.sendEmptyMessage(0);
}
});
thread.setDaemon(true);
thread.start();
}
});
如果您只想从i = 1-10秒计算,您甚至不需要使用线程,只需通过循环和调用使用postMessageDelayed:
myHandler.sendEmptyMessageDelayed(0, 1000); // what 0, 1 second
您可以在消息中传递(最好是不可变的)数据,如下所示:
Message msg= Message.obtainMessage(0);
Bundle b= new Bundle();
b.putString("stringData",outString);
msg.setData(b);
handler.sendMessage(msg);
并按以下方式检索:
Bundle b= msg.getData();
String data="";
if (b != null){
data= b.getString("stringData");
}
如果你只需要一个额外的线程,我会使用asyncTask。