Android中进程与线程及如何在子线程中操作UI线程
1. Android进程
一个应用程序被启动时,系统默认创建执行一个叫做"main"的线程。这个线程也是你的应用与界面工具包(android.widget和android.view包中的组件)交互的地方。于是main线程也被称为界面线程。
这种单线程的模式会带来低性能,除非你能正确的优化你的程序。
打个比方:用户触摸屏幕上的一个按钮时的点击事件即向线程中派发事件,比如每一个事件为一辆车。而每一条线程都好像是一条单行线的单车道。这条车道上的车量都排成队行驶至收费口进行事件处理。当处理的事件繁琐,比如在响应用户交互时需执行大量运算,或者像是执行网络连接、数据库请求这样耗时的操作。就会造成拥堵,将会阻止整个界面的响应。当线程被阻塞时,就不能派发事件了。从用户的角度看,程序反应太慢了。甚至更糟的是,如果界面线程被阻塞几秒钟(大5秒钟吧),用户就户抱怨说程序没反应了,用户可能因而退出并删掉你的应用。 此外,Andoid界面不是线程安全的。所以你绝不能在一个工作线程中操作你的界面—你只能在界面线程中管理的你的界面。所以,对于单线程模式有两个简单的规则
1不要阻塞界面线程
2不要在界面线程之外操作界面。
2. 工作线程
由于上述的单线程模式,不要阻塞你的界面线程以使你的应用的界面保持响应是非常重要的,那么如果你有不能很快完成的任务,你应把它们放在另一个线程中执行(后台线程或工作线程)。
例如,下面是的代码是响应click事件,在另外一个线程中从网络获取资源文字并以TextView来显示。
- mHandle.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- // 耗时操作
- loadNetWork();
- mTextView.setText(来自网络的文字);
- }
- });
- }
- });
第一眼,这看起来能很好的工作,因为它创建了一个新线程来进行网络操作。然而它违反了第二条规则:不要在界面线程之外操作界面—它简单的在工作线程中修改了mTextView。这会导至未定义的异常出现,并且难以调试追踪。
为了能改正这个问题,Android提供了很多从其它线程来操作界面的方法。下面是可用的方法们:
1 Activity.runOnUiThread(Runnable)
2 View.post(Runnable)
3 View.postDelayed(Runnable,long)
4 Handler
5 AsyncTask
现在我们就依次使用这几个方法:
1、Activity.runOnUiThread(Runnable)
- mHandle.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- MainActivity.this.runOnUiThread(new Runnable() {
- // 耗时操作
- loadNetWork();
- @Override
- public void run() {
- mTextView.setText(来自网络的文字);
- }
- });
- }
- });
- }
- });
2、View.post(Runnable)
- mHandle.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- // 耗时操作
- loadNetWork();
- mTextView.post(new Runnable() {
- @Override
- public void run() {
- mTextView.setText(来自网络的文字);
- }
- });
- }
- });
- }
- });
3、View.postDelayed(Runnable,long)
- mHandle.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- // 耗时操作
- loadNetWork();
- mTextView.postDelayed(new Runnable() {
- @Override
- public void run() {
- mTextView.setText(来自网络的文字);
- }
- }, 10);
- }
- });
- }
- });
4、Handler(子线程调用Handler的handle.sendMessage(msg);
- Handler handle = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- mTextView.setText(来自网络的文字);
- }
- };
- class MyThread extends Thread {
- @Override
- public void run() {
- // 耗时操作
- loadNetWork();
- Message msg = new Message();
- handle.sendMessage(msg);
- super.run();
- }
- }
5、AsyncTask
主线程中:aTask ak = new aTask(); ak.execute();
然后:
- private class aTask extends AsyncTask {
- //后台线程执行时
- @Override
- protected Object doInBackground(Object... params) {
- // 耗时操作
- return loadNetWork();
- }
- //后台线程执行结束后的操作,其中参数result为doInBackground返回的结果
- @Override
- protected void onPostExecute(Object result) {
- super.onPostExecute(result);
- mTextView.setText(result);
- }
- }
Android中进程与线程及如何在子线程中操作UI线程的更多相关文章
- Android 关于操作UI线程
在非UI线程里访问 Android UI toolkit—这个在一个worker线程修改了 View .这会导致不可预期的结果,而且还难以调试. 为了修复这个问题,Android提供了几个方法从非UI ...
- Android 操作UI线程的一些方法
我们经常会在后台线程中去做一些耗时的操作,比如去网络取数据.但是当数据取回来,需要显示到页面上的时候,会遇到一些小麻烦,因为我们都知道,android的UI页面是不允许在其他线程直接操作的.下面总结4 ...
- 在子jsp页面中调用父jsp中的function或父jsp调用子页面中的function
项目场景: A.jsp中有一个window,window里嵌入了一个<iframe>,通过<iframe>引入了另一个页面B.jsp.在B.jsp中的一个function中需要 ...
- jquery 中选择当前标签下众多相同子标签中的第n个
可以用jquery选择器的:eq选择器或者jquery遍历的eq()方法,下面带那给出ul下第4个li的内容 $("ul li:eq(3)") // 元素的index位置工0开始 ...
- Android 的进程和线程
进程和线程 如果某个应用程序组件是第一次被启动,且这时应用程序也没有其他组件在运行,则android系统会为应用程序创建一个包含单个线程的linux进程.默认情况下,同一个应用程序的所有组件都运行在同 ...
- Android中UI线程与后台线程交互设计的5种方法
我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必 ...
- Android中后台线程如何与UI线程交互
我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必须 ...
- Android UI线程和非UI线程
Android UI线程和非UI线程 UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这 ...
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
Android应用的开发过程中需要把繁重的任务(IO,网络连接等)放到其他线程中异步执行,达到不阻塞UI的效果. 下面将由浅入深介绍Android进行异步处理的实现方法和系统底层的实现原理. 本文介绍 ...
随机推荐
- HDU - 1874 畅通工程续(最短路径)
d.已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离. s.最短路径 c.Dijkstra单源最短路 /* Dijkstra单源最短路 权值必须是非负 单源最短路径,Dijkstra算法 ...
- 【字符串】BZOJ上面几个AC自动机求最为字串出现次数的题目
(一下只供自己复习用,目的是对比这几个题,所以写得不详细.需要细节的可以参考其他博主) [BZOJ3172:单词] 题目: 某人读论文,一篇论文是由许多(N)单词组成.但他发现一个单词会在论文中出现很 ...
- BZOJ_2097_[Usaco2010 Dec]Exercise 奶牛健美操_二分答案+树形DP
BZOJ_2097_[Usaco2010 Dec]Exercise 奶牛健美操_二分答案+树形DP Description Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间 的 ...
- Leetcode字符串专题
Leetcode38. Count and Say 分析:根据题意,数列的下一项就是统计上一项中每个数字出现的次数,理解清楚题意就很简单了 class Solution { public: strin ...
- 【POJ 3461】 Oulipo
[题目链接] 点击打开链接 [算法] KMP [代码] #include <algorithm> #include <bitset> #include <cctype&g ...
- 区间DP 等腰三角形
题目描述:给定一个正N边形,可以通过连线将这个多边形分割成N-2个三角形,问这N-2个三角形中恰有k个等腰三角形的分割方法有多少?这个值可能很大,输出对9397取模的结果.数据范围:n,k <= ...
- Ruby: Print WIN32OLE method names in Ruby
class WIN32OLE def list_ole_methods method_names = ole_methods.collect {|m| m.name} puts m ...
- 如何给lemon开无限栈
进入终端 输入"ulimit -s unlimited" 输入"lemon" 把lemon源程序拖进来,接着在弹出的lemon界面上操作即可.
- 启动和测试oracle是否安装成功
转自:https://www.cnblogs.com/justdo-it/articles/5112576.html 测试步骤1:请执行操作系统级的命令:tnsping orcl 测试步骤 2:请执行 ...
- E20180410-sl
category n. 类型,部门,种类,类别,类目; [逻,哲] 范畴; 体重等级;