- 浏览: 283972 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (142)
- android (64)
- android team 应用开发流程 (0)
- android 个人 开发流程 (1)
- android UI 切换皮肤 (1)
- java (9)
- 敏捷开发 (1)
- git (1)
- 学习 (2)
- hibernate (0)
- jQuery (1)
- windows (2)
- tomcat (1)
- Spring (3)
- struts2 (5)
- mysql (4)
- linux (15)
- JBPM (2)
- maven (4)
- 企业管理 (1)
- Iphone (1)
- 工作计划 (0)
- news (1)
- MOVE (1)
- exception-android (1)
- RFID (1)
- 测试 (7)
- android基础 (1)
- Gson (1)
- Android中的单元测试 (1)
最新评论
-
jlees:
Nice post.i hope this will help ...
Business mobile application development. The developer’s insight. -
weisi2375:
确实很详细的开发流程。
Android应用开发全流程 -
mikefather:
不错不错
Android,谁动了我的内存 -
ylzyd12345:
mark一下,谢谢分享
android的一些开源项目 -
limingcai:
确实不行,2.2就不行了,虽说2.3了 只有1.6可以
Android完全关闭应用程序
当应用程序启动,创建了一个叫“main”的线程,用于管理UI相关,又叫UI线程。其他线程叫工作线程(Work Thread)。
Single Thread Model
- 一个组件的创建并不会新建一个线程,他们的创建都在UI线程中进行,包括他们的回调方法,如onKeyDown()。
- 当在UI线程中进行某些耗时的操作时,将会阻塞UI线程,一般阻塞超过5秒就会显示一个ANR对话框。
-
UI线程是非线程安全的,所以,不能在工作线程中操作UI元素。
两个原则
- Do not block the UI thread (不要阻塞UI线程)
- Do not access the Android UI toolkit from outside the UI thread (不要在工作线程中操作UI元素)
在工作线程更新UI方法
- Activity.runOnUiThread(Runnable)
-
Handler
- sendMessage(Message)
- post(Runnable)
-
AsyncTask
- execute()
- doInBackground()
- onPostExecute()
例子程序
-
HandlerActivity01
- 在工作线程中进行UI操作。
-
HandlerActivity02
- Handler的两个重要方法:sendMessage和post。
-
HandlerActivity03
- 官方推荐最佳方法。
HandlerActivity01主要代码:
- btnEnd.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- new Thread(new Runnable() {
- @Override
- public void run()
- {
- //在新建的线程(工作线程)中改变Button的文字
- btnEnd.setText("Text Changed in Sub Thread");
- }
- }).start();
- }
- });
这是一种错误的做法,运行程序,会报错误:
- android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
HandlerActivity02主要代码:
- public class HandlerActivity02 extends Activity
- {
- private int title = 0;
- Button btnStart,btnEnd;
- private Handler mHandler = new Handler()
- {
- public void handleMessage(Message msg)
- {
- //更新UI
- switch (msg.what)
- {
- case 1:
- updateTitle();
- break;
- }
- };
- };
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- btnStart = (Button)findViewById(R.id.start);
- btnEnd = (Button)findViewById(R.id.end);
- //新启动一个线程,进行耗时操作
- Timer timer = new Timer();
- //每六秒执行一次MyTask的run方法
- timer.scheduleAtFixedRate(new MyTask(this), 1, 6000);
- }
- private class MyTask extends TimerTask
- {
- private Activity context;
- MyTask(Activity context)
- {
- this.context = context;
- }
- @Override
- public void run()
- {
- //耗时操作略....
- //更新UI方法 1
- Message message = new Message();
- message.what = 1;
- mHandler.sendMessage(message);
- //更新UI方法 2
- mHandler.post(updateThread);
- //更新UI方法 3
- context.runOnUiThread(updateThread);
- }
- }
- public void updateTitle()
- {
- setTitle("Welcome to Mr Wei's blog " + title);
- title++;
- }
- Runnable updateThread = new Runnable()
- {
- @Override
- public void run()
- {
- //更新UI
- btnStart.setText(String.valueOf(title));
- btnEnd.setText(String.valueOf(title));
- }
- };
- }
这里有个容易出错的地方,在更新UI方法2和3中,我们传入的参数是一个Runnable对象,一般认为这就会启动一个新的线程,而且常有人在这个Runnable对象的run方法中进行耗时操作。看过这块的源码就会知道,其实,android只是调用了这个Runnable对象的run方法而已,并没有启动新的线程,而且我们不应该在run方法中进行耗时操作,因为这个run方法最终是在UI线程里面执行的。也就是说,run方法里面只应该放更新UI的代码,handleMessage方法也一样。
如果你要看这部分源代码的话,相信这个图对你会有帮助:
HandlerActivity03主要代码:
- public class HandlerActivity03 extends Activity
- {
- Button btnStart;
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- btnStart = (Button)findViewById(R.id.start);
- btnStart.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- //开始执行AsyncTask,并传入某些数据
- new LongTimeTask().execute("New Text");
- }
- });
- }
- private class LongTimeTask extends AsyncTask<String, Void , String>
- {
- @Override
- protected String doInBackground(String... params)
- {
- try
- {
- //线程睡眠5秒,模拟耗时操作,这里面的内容Android系统会自动为你启动一个新的线程执行
- Thread.sleep(5000);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- return params[0];
- }
- @Override
- protected void onPostExecute(String result)
- {
- //更新UI的操作,这里面的内容是在UI线程里面执行的
- btnStart.setText(result);
- }
- }
- }
这个方法确实挺好,因为它为你封装了许多操作,你只需要记住在doInBackground方法中写耗时操作的代码,在onPostExecute方法中写更新UI的方法就行了。
发表评论
-
Resource-type-->Color State List Resource
2013-04-22 10:50 1664Color State List Resource Col ... -
Business mobile application development. The developer’s insight.
2012-11-07 17:49 1644from: http://www.enterra-inc.co ... -
Android. Handling some SQLite issues.
2012-11-07 17:48 1776转载: http://www.enterra-inc.com/ ... -
git 获取android source
2012-08-15 12:52 3680在做android开发的时,在遇到某一问题,想看andro ... -
Android 手机上获取物理唯一标识码
2012-07-27 10:27 11767唯一标识码这东西在网络应用中非常有用,例如检测是否 ... -
android listview adapter
2012-06-23 14:41 1017listview 在什么情况下会刷新: 1. 当ada ... -
Android多线程下载详解
2012-06-20 18:31 941http://www.pin5i.com/showtopic- ... -
Unable to open sync connection!
2012-06-18 17:04 965把设置里的USB调试重新开了开,问题解决! -
android checkbox 定制(修改checkbox 的图片)
2012-06-18 14:30 3646转载:http://www.bangchui.org/read ... -
Android ProgressBar自定义图片进度,自定义渐变色进度条
2012-06-15 16:53 7591 -
Android应用开发全流程
2012-06-15 09:21 3777转载:http://blog.csd ... -
intent.setDataAndType
2012-06-13 18:24 74861. Intent open a picture ... -
Android操作HTTP实现与服务器通信
2012-06-03 14:47 1743本示例以Servlet为例,演示Android与Serv ... -
这篇文章是android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用。 1.签名的意义 为了保证每个应用程序开发商合法ID,防止部分开
2012-05-25 13:58 1524这篇文章是android开发人员的必备知识,是我特别为大 ... -
android Collections.sort(List<T> list) 与JAVA Collections.sort(List<T> list)
2012-05-04 10:33 1858Info.java : public class In ... -
android string xliff:g
2012-03-22 10:47 1019这个主要用于程序中,动态的插入内容时候使用,例如, ... -
android的一些开源项目
2011-12-07 17:13 2169转自: http://www.uuroid.com ... -
Understanding the Android Build Process
2011-11-25 12:38 975http://www.alittlemadness.com/2 ... -
Android 命令行手动编译打包详解
2011-11-24 10:07 1246Android 命令行手动编译打包过程图 【详细步骤】: 1 ... -
Android ListView 自定义背景后 滚动时的背景变黑问题
2011-11-21 14:30 1551ListView是常用的显示控件, ...
相关推荐
在Android开发中,`android.view.ViewRootImpl$CalledFromWrongThreadException` 是一个常见的异常,它通常发生在尝试在非UI线程(主线程)中修改用户界面元素时。这个异常表明,只有创建视图的原始线程(即主线程)...
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.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 这个异常为何不是 Only the main thread that created a view hierarchy ...
本文实例讲述了Android实现在子线程中更新Activity中...ERROR/AndroidRuntime(1222): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its
如果是在WT进行UI的更新,则会抛出异常,android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.(只有创建这个View的原
在这种情况下,需要开启新的线程,但不能直接访问View对象,因为这会报android.view.ViewRoot$CalledFromWrongThreadException异常。为了解决这个问题,需要创建一个继承了android.os.Handler的子类,并重写...
否则可能会导致`Android.view.ViewRootImpl$CalledFromWrongThreadException`异常。 7. **不同类型的Toast**:五种效果可能包括信息提示、警告、成功状态、错误状态等,每种类型对应不同的图标和颜色,以增强用户...
4. **运行时动态更新UI**:因为是运行时添加,所以需要确保所有操作都在UI线程上执行,否则可能会抛出`android.view.ViewRootImpl$CalledFromWrongThreadException`异常。可以使用`runOnUiThread()`或者`Handler`来...
- **主线程**:Android应用的UI更新必须在主线程(也称为应用或UI线程)中进行,否则会抛出`Android.view.ViewRootImpl$CalledFromWrongThreadException`异常。 - **工作线程**:用于执行耗时操作,如网络请求、...
- 不要在非UI线程中更新UI,这将抛出` android.view.ViewRootImpl$CalledFromWrongThreadException`异常。 8. **源码分析**: 对于进阶学习,了解`Handler`、`Looper`和`MessageQueue`的源码有助于深入理解它们的...
4. **子线程更新UI问题**:Android系统规定,只有主线程可以修改UI元素,子线程直接修改会导致`android.view.ViewRootImpl$CalledFromWrongThreadException`异常。为了解决这个问题,提供了以下方法: - `...
构建了一个轻量级的消息通信机制,使得我们可以在不同的线程间进行数据交互,更新UI,避免了直接在非UI线程操作UI导致的`Android.view.ViewRootImpl$CalledFromWrongThreadException`异常。 `Handler`的工作原理...
此外,避免在非UI线程中更新UI,否则会导致` android.view.ViewRootImpl$CalledFromWrongThreadException`异常。 了解并熟练掌握Handler机制对于Android开发者来说至关重要,它能够帮助我们实现复杂的异步操作,...
Android UI操作必须在主线程(UI线程)中执行,否则会抛出`android.view.ViewRootImpl$CalledFromWrongThreadException`异常。因此,在子线程中进行倒计时计算后,我们需要使用`Handler`或`runOnUiThread`来更新UI。...
在使用 dialog 的时候,因为线程问题,在调用 dismiss() 方法的时候,出现如下常见的 crash–Only the original thread that created a view hierarchy can touch its views.,堆栈信息如下: threadName:main,...
- 由于异常处理是在主线程中进行的,因此在显示对话框或执行其他UI操作时,需要确保在正确的线程中进行,否则可能会出现`Android.view.ViewRootImpl$CalledFromWrongThreadException`的错误。 - 记录异常信息时,...
然而,Service通常运行在自己的工作线程中,这意味着在Service中直接使用Toast可能会导致`android.view.ViewRootImpl$CalledFromWrongThreadException`异常。为了解决这个问题,有以下两种常见方法: 1. 使用`...
如果在非UI线程中尝试修改UI元素,会抛出`android.view.ViewRoot$CalledFromWrongThreadException`异常。 为了确保用户界面的响应性,避免主线程被长时间阻塞,耗时的操作如网络请求、数据库操作等应当在其他线程中...