- 浏览: 278417 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (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 1618Color State List Resource Col ... -
Business mobile application development. The developer’s insight.
2012-11-07 17:49 1607from: http://www.enterra-inc.co ... -
Android. Handling some SQLite issues.
2012-11-07 17:48 1749转载: http://www.enterra-inc.com/ ... -
git 获取android source
2012-08-15 12:52 3644在做android开发的时,在遇到某一问题,想看andro ... -
Android 手机上获取物理唯一标识码
2012-07-27 10:27 11702唯一标识码这东西在网络应用中非常有用,例如检测是否 ... -
android listview adapter
2012-06-23 14:41 978listview 在什么情况下会刷新: 1. 当ada ... -
Android多线程下载详解
2012-06-20 18:31 903http://www.pin5i.com/showtopic- ... -
Unable to open sync connection!
2012-06-18 17:04 904把设置里的USB调试重新开了开,问题解决! -
android checkbox 定制(修改checkbox 的图片)
2012-06-18 14:30 3592转载:http://www.bangchui.org/read ... -
Android ProgressBar自定义图片进度,自定义渐变色进度条
2012-06-15 16:53 7550 -
Android应用开发全流程
2012-06-15 09:21 3709转载:http://blog.csd ... -
intent.setDataAndType
2012-06-13 18:24 74151. Intent open a picture ... -
Android操作HTTP实现与服务器通信
2012-06-03 14:47 1693本示例以Servlet为例,演示Android与Serv ... -
这篇文章是android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用。 1.签名的意义 为了保证每个应用程序开发商合法ID,防止部分开
2012-05-25 13:58 1464这篇文章是android开发人员的必备知识,是我特别为大 ... -
android Collections.sort(List<T> list) 与JAVA Collections.sort(List<T> list)
2012-05-04 10:33 1814Info.java : public class In ... -
android string xliff:g
2012-03-22 10:47 984这个主要用于程序中,动态的插入内容时候使用,例如, ... -
android的一些开源项目
2011-12-07 17:13 2122转自: http://www.uuroid.com ... -
Understanding the Android Build Process
2011-11-25 12:38 929http://www.alittlemadness.com/2 ... -
Android 命令行手动编译打包详解
2011-11-24 10:07 1213Android 命令行手动编译打包过程图 【详细步骤】: 1 ... -
Android ListView 自定义背景后 滚动时的背景变黑问题
2011-11-21 14:30 1505ListView是常用的显示控件, ...
相关推荐
问题:android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a 我的场景是 LinearLayout.LayoutParams params11 = new LinearLayout.LayoutParams(264, LinearLayout....
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 ...
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中...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的原
在使用 dialog 的时候,因为线程问题,在调用 dismiss() 方法的时候,出现如下常见的 crash–Only the original thread that created a view hierarchy can touch its views.,堆栈信息如下: threadName:main,...
为什么可以在子线程通过setText进行更新UI ... Only the original thread that created a view hierarchy can touch its views.); } } 一般情况下在子线程更新UI是会报错的,因为在ViewRootImpl