`

Handler Only the original thread that created a view hierarchy can touch its vi

阅读更多

错误例子:这里使用的Barprogress 在结束后就会报异常,因为我们把控件放在了子线程中了。

package com.funo.cicerone;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class HandlerActivity extends Activity {

private TextView text = null;
private Button button = null;
private ProgressBar bar = null;

private MyHandler myHandler;

private MyThread m = new MyThread();

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.handle_activity);

text = (TextView) findViewById(R.id.text);
button = (Button) findViewById(R.id.button);
bar = (ProgressBar) findViewById(R.id.bar);
bar.setMax(100);
button.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
myHandler = new MyHandler();

new Thread(m).start();
System.out.println("onCreate--The Thread is: "
+ Thread.currentThread().getId());

}
});
}

// 执行接收到的通知,此时执行的顺序是按照队列进行,即先进先出
class MyHandler extends Handler {

public MyHandler() {
}

public MyHandler(Looper l) {
super(l);
}

@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
System.out.println("Handler--The ThreadId is: "
+ Thread.currentThread().getId());
Bundle b = msg.getData();
String textStr1 = text.getText().toString();
String textStr2 = b.getString("textStr");
System.out.println(textStr1 + "..." + textStr2 + ".......");
HandlerActivity.this.text.setText(textStr1 + " " + textStr2);// 更改TextView中的值
int barValue = b.getInt("barValue");
System.out.println(barValue + "....barValue...");
HandlerActivity.this.bar.setProgress(barValue);// 更改进度条当中的值
System.out.println(msg.what + "...msg.what...");

super.handleMessage(msg);
}
}

class MyThread implements Runnable {
int i = 1;

@Override
public void run() {
// TODO Auto-generated method stub
while (i < 11) {
System.out.println("Thread--The ThreadId is: "
+ Thread.currentThread().getId());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg = new Message();
Bundle b = new Bundle();
b.putString("textStr", "线程运行" + i + "次");
b.putInt("barValue", i * 10);
i++;
msg.setData(b);
HandlerActivity.this.myHandler.sendMessage(msg);// 通过sendMessage向Handler发送更新UI的消息
}
//在这里要消除ProgressBar 会报异常。
bar.setVisibility(View.GONE);
}
}
}


异常:
03-16 09:32:32.314: ERROR/AndroidRuntime(21751): FATAL EXCEPTION: Thread-8
03-16 09:32:32.314: ERROR/AndroidRuntime(21751): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-16 09:32:32.314: ERROR/AndroidRuntime(21751):     at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
03-16 09:32:32.314: ERROR/AndroidRuntime(21751):     at android.view.ViewRoot.requestLayout(ViewRoot.java:594)
03-16 09:32:32.314: ERROR/AndroidRuntime(21751):     at android.view.View.requestLayout(View.java:8125)
03-16 09:32:32.314: ERROR/AndroidRuntime(21751):     at android.view.View.requestLayout(View.java:8125)
03-16 09:32:32.314: ERROR/AndroidRuntime(21751):     at android.view.View.requestLayout(View.java:8125)
03-16 09:32:32.314: ERROR/AndroidRuntime(21751):     at android.view.View.requestLayout(View.java:8125)
03-16 09:32:32.314: ERROR/AndroidRuntime(21751):     at android.view.View.requestLayout(View.java:8125)
03-16 09:32:32.314: ERROR/AndroidRuntime(21751):     at android.view.View.setFlags(View.java:4501)
03-16 09:32:32.314: ERROR/AndroidRuntime(21751):     at android.view.View.setVisibility(View.java:3030)
03-16 09:32:32.314: ERROR/AndroidRuntime(21751):     at android.widget.ProgressBar.setVisibility(ProgressBar.java:767)
03-16 09:32:32.314: ERROR/AndroidRuntime(21751):     at com.funo.cicerone.HandlerActivity$MyThread.run(HandlerActivity.java:144)
03-16 09:32:32.314: ERROR/AndroidRuntime(21751):     at java.lang.Thread.run(Thread.java:1096)


改进下:

package com.funo.cicerone;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class HandlerActivity extends Activity {

private TextView text = null;
private Button button = null;
private ProgressBar bar = null;

private MyHandler myHandler;

private MyThread m = new MyThread();

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.handle_activity);

text = (TextView) findViewById(R.id.text);
button = (Button) findViewById(R.id.button);
bar = (ProgressBar) findViewById(R.id.bar);
bar.setMax(100);
button.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
myHandler = new MyHandler();

new Thread(m).start();
System.out.println("onCreate--The Thread is: "
+ Thread.currentThread().getId());

}
});
}

// 执行接收到的通知,此时执行的顺序是按照队列进行,即先进先出
class MyHandler extends Handler {

public MyHandler() {
}

public MyHandler(Looper l) {
super(l);
}

@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
System.out.println("Handler--The ThreadId is: "
+ Thread.currentThread().getId());
Bundle b = msg.getData();
String textStr1 = text.getText().toString();
String textStr2 = b.getString("textStr");
System.out.println(textStr1 + "..." + textStr2 + ".......");
HandlerActivity.this.text.setText(textStr1 + " " + textStr2);// 更改TextView中的值
int barValue = b.getInt("barValue");
System.out.println(barValue + "....barValue...");

System.out.println(msg.what + "...msg.what...");

switch (barValue) {

case 10:

HandlerActivity.this.bar.setProgress(barValue);// 更改进度条当中的值
break;
case 20:

HandlerActivity.this.bar.setProgress(barValue);// 更改进度条当中的值
break;
case 30:

HandlerActivity.this.bar.setProgress(barValue);// 更改进度条当中的值
break;
case 40:

HandlerActivity.this.bar.setProgress(barValue);// 更改进度条当中的值
break;
case 50:

HandlerActivity.this.bar.setProgress(barValue);// 更改进度条当中的值
break;
case 60:

HandlerActivity.this.bar.setProgress(barValue);// 更改进度条当中的值
break;
case 70:

HandlerActivity.this.bar.setProgress(barValue);// 更改进度条当中的值
break;
case 80:

HandlerActivity.this.bar.setProgress(barValue);// 更改进度条当中的值
break;
case 90:

HandlerActivity.this.bar.setProgress(barValue);// 更改进度条当中的值
break;

case 100:
HandlerActivity.this.bar.setVisibility(View.INVISIBLE);
}
super.handleMessage(msg);

}
}

class MyThread implements Runnable {
int i = 1;

@Override
public void run() {
// TODO Auto-generated method stub

while (i < 11) {
System.out.println("Thread--The ThreadId is: "
+ Thread.currentThread().getId());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg = new Message();
Bundle b = new Bundle();
b.putString("textStr", "线程运行" + i + "次");
b.putInt("barValue", i * 10);
i++;
msg.setData(b);
HandlerActivity.this.myHandler.sendMessage(msg);// 通过sendMessage向Handler发送更新UI的消息
}
// bar.setVisibility(View.GONE);

}

}
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics