Android初识多线程

Android多线程

  • 一个Android的应用程序运行在一个独立的进程中,运行在一个独立的虚拟机(dvk)上。 (进程名为包名)

  • Android应用程序开启后,默认开启一个主线程(UI线程)
    Activity,Service,BroadcastReceiver组件运行在主线程中
    Android应用程序退出后,保留空UI线程,可以加快应用程序启动速度

  • 用户不能在UI主线程中做耗时的操作,一旦该操作超过5s,应用程序抛一个ANR异常(Application not respond)。
    如何避免ANR错误?
    将耗时的操作放入子线程中。(耗时的操作包括:长时间的休眠,计数,联网,复杂的运算。)

  • 只有主线程才能操作Widget控件。
    如果在子线程中操作Widget控件,系统抛出CalledFromWrongThreadException异常。

  • 系统为什么要这么做?
    避免出现同步问题。

Handler机制。

  • Goolge为什么设计这套机制?
    主要是为了解决非UI线程中不能更新Widget控件的问题

  • Handler机制剖析
    子线程发送消息给底层的消息队列。
    handler.sendMessage(msg)
    主线程查询消息队列,处理消息对象。
    handlerMessage(msg)
    MessageQueue 消息队列
    负责存储消息对象

  • Looper
    给UI线程安排代码,一个UI线程只能有一个Looper对象,否则多个Looper对象都在UI线程上安排代码,解决冲突就是个大问题。 Looper对象会线性安排在UI线程上执行的代码,它通过一个队列管理各个Handler对象提交的代码。

  • Message消息对象

//从消息池中获取消息对象
Message msg = handler.obtainMessage();
//在消息对象上绑定int类型数据
msg.arg1 = count;
//在消息对象上绑定其它类型数据
msg.setData(Bundle);        //Bundler为数据集(类似于HashMap容器)
  • 向消息队列发送消息,1000毫秒后执行Runnable对象中的代码。
myHandler.postDelayed(new Runnable() { 
           @Override 
          public void run() { 
                 // TODO Auto-generated method stub 
                 Log.e("Test", "thread name = "+Thread.currentThread().getName());
           }
}, 1000);

异步任务(AsyncTask)

  • 概念
    封装多线程和Handler机制。给用户提供重写接口的方式,不需要用户手动创建子线程和Handler对象。

  • 异步任务的优点
    Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI主线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但是也有缺点,代码臃肿,在多个任务同时执行时,不易对线程进行精确的控制。为了简化操作,Android1.5提供了一个工具类AsyncTask,它是创建异步任务变的更加简单,不再需要编写任务线程和Handler实例就可完成任务。

  • 异步任务的局限性
    多个异步任务不能同时执行,在某个时间内,只能执行一个异步任务。

  • 执行异步任务的步骤:

  1. execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
  2. onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
  3. doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调publishProgress(Progress... values)来更新进度信息。
  4. onProgressUpdate(Progress... values),在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。
  5. onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。
  • 取消异步任务
/** 
*cancel(true) 取消当前的异步任务,传入的true,表示当中断异步任务时继续已经运行的线程的操作, 
*但是为了线程的安全一般为让它继续设为true 
**/ 
mTask.cancel(true); 
/** 
* 但是重新运行后会发现还是不能起到效果, 
* 注意:这是因为cancel方法只是发出一个请求取消异步任务的信号, 
* 将对应当前的异步任务标记为CANCEL状态,而并不是真正取消线程的执行,
 * 而此时异步任务中的线程仍然在执行并没有结束 
* 所以效果依然是这样的,并且在java中我们是无法直接暴力将一个线程给停止掉
 * 既然我们知道无法去取消一个已经正在运行的线程,但是我们如何去解决这个BUG呢? 
* 在异步任务中还给我们提供一个isCanceled的回调方法,也就是当我已经给当前的异步任务 
* 调用了cancel(true)方法,发出一个请求取消异步任务的信号,那么此时的isCanceled的回调方法 
* 会直接返回一个true,那么我们就可以通过判断当前异步任务isCanceled是否为true,来终止
* 线程中的操作而不是去终止线程,从而达到了界面显示好像线程中的操作被终止了,而实际上 
* 该线程依然在运行
* */
  • 注意
  1. 异步任务对象只能执行一次。
  2. 异步任务对象必须在UI主线程中创建。execute(Params... params)方法必须在UI线程中调用。
  3. 不要手动调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法。
  4. 不能在doInBackground(Params... params)中更改UI组件的信息。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容