使用线程更新两个连续的文本视图

时间:2011-05-16 19:37:43

标签: android multithreading

我一直在阅读我的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

有什么想法吗?

2 个答案:

答案 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是您的活动,textView1textView2是您要更新的文字视图。

答案 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。