`

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);

}

}
}
分享到:
评论

相关推荐

    Android studio :后台修改前台界面Only the original thread that created a view hierarchy can touch its views

    Only the original thread that created a view hierarchy can touch its views 这句话的意思是:只有创建这个view的线程才能操作这个view 解决方法就是handle 1、 Handler mHandler; 2、 mHandler = new Handler();...

    开新线程引发的常见3个异常

    2.android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 3.java.lang.RuntimeException: Can't create handler inside thread ...

    Android实现在子线程中更新Activity中UI的方法

    本文实例讲述了Android实现在子线程中更新Activity中...ERROR/AndroidRuntime(1222): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its

    Android消息机制基本原理和使用

    例如在子线程进行耗时较长的下载,等下载完成之后,再去更新UI,提示用户下载完成,直接在子线程里更新UI,会得到报错提示:Only the original thread that created a view hierarchy can touch its views。...

    Xamarin.Android 非UI线程更新UI

    如果在非UI线程中直接修改UI元素,系统会抛出`Android.Content.ReceiverNotRegisteredException`或`Java.Lang.RuntimeException: Only the original thread that created a view hierarchy can touch its views.`...

    Android:Handler的post()方法和Thread的start()方法执行Thread的run()方法的区别

    System.out.println("Handler--&gt;"+Thread.currentThread().getName()); } }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if ...

    详解Android UI更新的几种方法

    如果是在 WT 进行 UI 的更新,则会抛出异常,android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views。 Android UI 更新的方法有多种...

    Android延时操作的三种方法

    前两种方法在更新 UI 时,如果不使用消息处理机制的话,会报错,例如 "Only the original thread that created a view hierarchy can touch its views."(只能在主线程中更新 UI)。因此,在使用延时操作时,推荐...

    问题:android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original

    在Android开发中,`android.view.ViewRootImpl$CalledFromWrongThreadException` 是一个常见的异常,它通常发生在尝试在非UI线程(主线程)中修改用户界面元素时。这个异常表明,只有创建视图的原始线程(即主线程)...

    Handler + Thread + Looper

    在Android应用开发中,Handler、Thread和Looper是三个至关重要的组件,它们共同构成了Android线程间通信的基础架构。本文将详细解析这三个概念及其相互关系,旨在帮助开发者理解它们的工作原理和实际应用场景。 ...

    Handler+Thread

    在Android应用开发中,`Handler` 和 `Thread` 是两个非常关键的概念,它们主要用于处理线程间的通信和异步操作。下面将详细解释这两个概念,以及如何在实际应用中使用它们来实现简单的网络图片获取和显示。 首先,`...

    android service thread toast handler

    在Android开发中,`Service`、`Thread`、`Toast`和`Handler`是四个非常重要的组件和概念,它们在创建高效、响应式的应用程序中起着关键作用。下面将详细阐述这些知识点及其相互关系。 首先,`Service`是Android中的...

    测试Thread中使用Handler修改

    在Android开发中,`Thread` 和 `Handler` 是两个非常重要的概念,它们是实现多线程通信的关键工具。本文将详细解析如何在`Thread`中使用`Handler`来修改主线程(UI线程)的数据或者更新UI。 首先,我们要了解`...

    关于Thread和Handler的使用(一)

    在Android开发中,Thread和Handler是两个非常关键的概念,它们用于处理线程间通信和UI更新,确保程序的运行效率和用户体验。这篇博客主要探讨了如何有效地使用Thread和Handler进行多线程操作。 首先,Thread在Java...

    Thread_Handler_MessageDownload.zip

    本项目"Thread_Handler_MessageDownload"着重探讨了如何利用Thread、Handler和Message机制实现异步下载网络图片,确保UI线程不被阻塞,提高应用的响应速度。 首先,我们需要了解Android系统对线程的管理。在Android...

    Android Thread Handler

    在Android应用开发中,线程(Thread)和Handler是实现多任务并行处理以及界面更新的关键组件。Android系统是一个单线程模型,主线程(UI线程)负责处理用户交互和绘制界面,而其他工作通常需要在后台线程中执行,以...

    AsyncTask 与Thread加Handler处理消息比较

    本篇文章将详细探讨两种常见的异步处理方式:`AsyncTask`和`Thread`配合`Handler`,并进行对比分析。 `AsyncTask`是Android SDK提供的一种轻量级的异步任务处理机制,它主要用于短时间的后台操作,如网络请求、数据...

    VC技术内幕第五版.chm

    such as how to write a message handler with ClassWizard, I thereafter let the source code do the talking and assume that you can figure out how the source code was created. Keep in mind that the ...

Global site tag (gtag.js) - Google Analytics