1. Android进程

一个应用程序被启动时,系统默认创建执行一个叫做"main"的线程。这个线程也是你的应用与界面工具包(android.widget和android.view包中的组件)交互的地方。于是main线程也被称为界面线程。

这种单线程的模式会带来低性能,除非你能正确的优化你的程序。

打个比方:用户触摸屏幕上的一个按钮时的点击事件即向线程中派发事件,比如每一个事件为一辆车。而每一条线程都好像是一条单行线的单车道。这条车道上的车量都排成队行驶至收费口进行事件处理。当处理的事件繁琐,比如在响应用户交互时需执行大量运算,或者像是执行网络连接、数据库请求这样耗时的操作。就会造成拥堵,将会阻止整个界面的响应。当线程被阻塞时,就不能派发事件了。从用户的角度看,程序反应太慢了。甚至更糟的是,如果界面线程被阻塞几秒钟(大5秒钟吧),用户就户抱怨说程序没反应了,用户可能因而退出并删掉你的应用。 此外,Andoid界面不是线程安全的。所以你绝不能在一个工作线程中操作你的界面—你只能在界面线程中管理的你的界面。所以,对于单线程模式有两个简单的规则

1不要阻塞界面线程

2不要在界面线程之外操作界面。

2. 工作线程

由于上述的单线程模式,不要阻塞你的界面线程以使你的应用的界面保持响应是非常重要的,那么如果你有不能很快完成的任务,你应把它们放在另一个线程中执行(后台线程或工作线程)。

例如,下面是的代码是响应click事件,在另外一个线程中从网络获取资源文字并以TextView来显示。

  1. mHandle.setOnClickListener(new OnClickListener() {
  2. @Override
  3. public void onClick(View v) {
  4. new Thread(new Runnable() {
  5. @Override
  6. public void run() {
  7. // 耗时操作
  8. loadNetWork();
  9. mTextView.setText(来自网络的文字);
  10. }
  11. });
  12. }
  13. });

第一眼,这看起来能很好的工作,因为它创建了一个新线程来进行网络操作。然而它违反了第二条规则:不要在界面线程之外操作界面—它简单的在工作线程中修改了mTextView。这会导至未定义的异常出现,并且难以调试追踪。

为了能改正这个问题,Android提供了很多从其它线程来操作界面的方法。下面是可用的方法们:

1 Activity.runOnUiThread(Runnable)

2 View.post(Runnable)

3 View.postDelayed(Runnable,long)

4 Handler

5 AsyncTask

现在我们就依次使用这几个方法:

1、Activity.runOnUiThread(Runnable)

  1. mHandle.setOnClickListener(new OnClickListener() {
  2. @Override
  3. public void onClick(View v) {
  4. new Thread(new Runnable() {
  5. @Override
  6. public void run() {
  7. MainActivity.this.runOnUiThread(new Runnable() {
  8. // 耗时操作
  9. loadNetWork();
  10. @Override
  11. public void run() {
  12. mTextView.setText(来自网络的文字);
  13. }
  14. });
  15. }
  16. });
  17. }
  18. });

2、View.post(Runnable)

  1. mHandle.setOnClickListener(new OnClickListener() {
  2. @Override
  3. public void onClick(View v) {
  4. new Thread(new Runnable() {
  5. @Override
  6. public void run() {
  7. // 耗时操作
  8. loadNetWork();
  9. mTextView.post(new Runnable() {
  10. @Override
  11. public void run() {
  12. mTextView.setText(来自网络的文字);
  13. }
  14. });
  15. }
  16. });
  17. }
  18. });

3、View.postDelayed(Runnable,long)

  1. mHandle.setOnClickListener(new OnClickListener() {
  2. @Override
  3. public void onClick(View v) {
  4. new Thread(new Runnable() {
  5. @Override
  6. public void run() {
  7. // 耗时操作
  8. loadNetWork();
  9. mTextView.postDelayed(new Runnable() {
  10. @Override
  11. public void run() {
  12. mTextView.setText(来自网络的文字);
  13. }
  14. }, 10);
  15. }
  16. });
  17. }
  18. });

4、Handler(子线程调用Handler的handle.sendMessage(msg);

  1. Handler handle = new Handler() {
  2. @Override
  3. public void handleMessage(Message msg) {
  4. super.handleMessage(msg);
  5. mTextView.setText(来自网络的文字);
  6. }
  7. };
  1. class MyThread extends Thread {
  2. @Override
  3. public void run() {
  4. // 耗时操作
  5. loadNetWork();
  6. Message msg = new Message();
  7. handle.sendMessage(msg);
  8. super.run();
  9. }
  10. }

5、AsyncTask

主线程中:aTask ak = new aTask(); ak.execute();

然后:

    1. private class aTask extends AsyncTask {
    2. //后台线程执行时
    3. @Override
    4. protected Object doInBackground(Object... params) {
    5. // 耗时操作
    6. return loadNetWork();
    7. }
    8. //后台线程执行结束后的操作,其中参数result为doInBackground返回的结果
    9. @Override
    10. protected void onPostExecute(Object result) {
    11. super.onPostExecute(result);
    12. mTextView.setText(result);
    13. }
    14. }

Android中进程与线程及如何在子线程中操作UI线程的更多相关文章

  1. Android 关于操作UI线程

    在非UI线程里访问 Android UI toolkit—这个在一个worker线程修改了 View .这会导致不可预期的结果,而且还难以调试. 为了修复这个问题,Android提供了几个方法从非UI ...

  2. Android 操作UI线程的一些方法

    我们经常会在后台线程中去做一些耗时的操作,比如去网络取数据.但是当数据取回来,需要显示到页面上的时候,会遇到一些小麻烦,因为我们都知道,android的UI页面是不允许在其他线程直接操作的.下面总结4 ...

  3. 在子jsp页面中调用父jsp中的function或父jsp调用子页面中的function

    项目场景: A.jsp中有一个window,window里嵌入了一个<iframe>,通过<iframe>引入了另一个页面B.jsp.在B.jsp中的一个function中需要 ...

  4. jquery 中选择当前标签下众多相同子标签中的第n个

    可以用jquery选择器的:eq选择器或者jquery遍历的eq()方法,下面带那给出ul下第4个li的内容 $("ul li:eq(3)")  // 元素的index位置工0开始 ...

  5. Android 的进程和线程

    进程和线程 如果某个应用程序组件是第一次被启动,且这时应用程序也没有其他组件在运行,则android系统会为应用程序创建一个包含单个线程的linux进程.默认情况下,同一个应用程序的所有组件都运行在同 ...

  6. Android中UI线程与后台线程交互设计的5种方法

    我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必 ...

  7. Android中后台线程如何与UI线程交互

    我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必须 ...

  8. Android UI线程和非UI线程

    Android UI线程和非UI线程 UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这 ...

  9. Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面

    Android应用的开发过程中需要把繁重的任务(IO,网络连接等)放到其他线程中异步执行,达到不阻塞UI的效果. 下面将由浅入深介绍Android进行异步处理的实现方法和系统底层的实现原理. 本文介绍 ...

随机推荐

  1. JRE System Library 与Java EE Libraries的区别

    JRE System Library是只要做java开发都需要的完整的.标准的库.  Java EE5 Libraries只是java三个方向中做java EE所需要的库.如果做Web方面的开发的话就 ...

  2. .NET 的 WebSocket 开发包比较 【已翻译100%】--网址:http://www.oschina.net/translate/websocket-libraries-comparison-2

    编者按 本文出现在第三方产品评论部分中.在这一部分的文章只提供给会员,不允许工具供应商用来以任何方式和形式来促销或宣传产品.请会员报告任何垃圾信息或广告. Web项目常常需要将数据尽可能快地推送给客户 ...

  3. 「咕咕网校 - 基础省选」树上问题的进阶 by Drench

    一定要在noip之前把自己花钱买的Luogu网课梳理完!QAQ 树上前缀和: 对于有根树,在每个点记录 val (点权) 和 sum(到根的点权之和) 当然记录的值因题而异(但是既然叫树上前缀和当然就 ...

  4. 【前端】CentOS 7 系列教程之六: 安装 mysql 5.7

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/linux_6.html 进入/usr/local/src目录 cd /usr/local/src 下载mysql的 ...

  5. PhpStorm比较高级的一些设置

    开始使用phpstorm工具,总体感觉还是不错的.有点不舒服的就是他占用内存比较高,反应速度有时会卡,这跟他的功能强大有关系.有些功能对于 我来说是不怎么需要的,比如自动保存功能,会频繁的保存一些文件 ...

  6. Start Developing Mac Apps -- Mac App Store Mac 应用商店

      Mac App Store The information you’ve read so far focused on how to create an app in Xcode. However ...

  7. eclipse配置环境基本设置

    一.修改字符集编码 二修改字体 三.安装jre 四.修改jsp文件的默认字符集 五.展示想要的窗口 六.修改右键new的内容

  8. HDU 1270 小希的数表 (暴力枚举+数学)

    题意:... 析:我们可以知道,a1+a2=b1,那么我们可以枚举a1,那么a2就有了,并且a1+a3=b2,所以a3就有了,我们再从把里面的剩下的数两两相加,并从b数组中去掉, 那么剩下的最小的就是 ...

  9. J20170422-hm

    ワイルドスクリプト wild script 通配符 シェルスクリプト     shell脚本

  10. Thirft 客户端等待时间

    thrift框架使用C++ thrift shows CLOSE_WAIL error thrift中TNonblockingServer的简单用法