Android 多线程

为什么要使用多线程?

当我们需要发出一条网络请求时,由于各种原因(网速过慢、服务器繁忙),服务器不能及时响应我们的请求,若我们将此操作放在的Main Thread中就会出现界面卡顿,甚至会出现ANR问题,为了解决Main Thread被阻塞的问题,我们只能另辟蹊径——开启子线程。

主线程

Main Thread主要处理UI有关的事件,如:按钮的点击事件,用户触摸事件、绘图事件等,并把相应的事件分发给相应的组件去处理,所以主线程又被成为UI线程。

子线程

除UI线程之外的线程成为子线程,一般都处理比较耗时的操作,如下载上传,访问数据库,读写文件等

线程的三种基本使用方法

1.集成Thread,并重写run()方法

eg: class MyThread extends Thread{
       @Override
       public void run(){
       //处理具体的逻辑  
       }
}

启动线程时,需要new一个MyThread的实例,然后调用它的start()方法即可
2.直接实现Runnable接口

eg: class MyThread implements Runnable{
  @Override
       public void run(){
       //处理具体的逻辑
       }
}

启动方法

MyThread myThread=new MyThread();
new Thread(myThread).start();

3.匿名内部类的方式

new Thread (new Runnable(){
  @Override
  public void run(){
  //处理具体的逻辑
  }
  }).start();

主线程的主要职责是负责显示、处理、更新UI控件,管理子线程,子线程的职责是处理一些耗时的操作,若有需要也要向主线程发送更新UI的消息。但新的问题是子线程与主线程如何发送消息通信呢?在Android中,提供了两种方式解决线程通信问题。

方式一 Handler机制

android的异步处理机制有四部分组成:Meaasge、Handler、MessageQueue、Looper。

Meaasge

Meaasge是在线程之间传递消息,它可以在内部携带少量的信息,用于在不同的线程之间交换数据,如:Message的what字段,arg1和arg2字段携带一些整形数据、object携带Object对象。

Handler

主要是用于发送和处理消息,发送消息一般使用Handler的sendMessage()方法,发送的消息最终会传到Handler的handlerMessage()方法中。

MessageQueue

MessageQueue是消息队列的意思,它主要用于存放所有通过Handler发送的消息,部分消息会一直存在于消息队列中等待被处理,每个线程中只会有一个MessageQueue对象。

Looper

Looper是每个线程中MessageQueue的管家,调用Looper的loop()方法,就会进入到一个无限循环中,每当发现MeaasgeQueue中有消息,就会将该消息拿出来,并传递到Handler的handlerMessage()方法中。每个线程也只有一个Looper对象。

方式一 AsynTask

Android的AsynTask异步任务是比Handler更轻量级一些,适用于简单的异步处理。AsynTask就是一个封装过的后台任务类。我们可以将耗时的操作放在异步任务中来处理,并随时将任务执行的结果返回给我们的UI线程来更新我们的UI控件。AsynTask直接继承于Object类,位置为android.os.AsynTask,要使用AsynTask我们提供三个泛型参数并重载几个方法

AsynTask定义三种泛型类型 Params, Progress,Result
1)Params 启动任务执行的输入参数,比如HTTP求情的URL
2)Progress 后台任务执行的百分比
3)Result 后台任务执行的最终结果

使用AsynTask异步加载数据最少要重写一下这两种方法:
1) doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里处理,注意这里不能直接操作UI,此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间,在执行过程中可以调用publishProgress(Progress…)来更新任务进度。
2)onPostExecute(Result) 相当于Handler处理UI的方式,在这里可以使用doInBackground得到的结果处理操作UI,此方法在主线程中执行,任务执行的结果作为此方法的参数返回。
3)onProgressUpdate(Progress…) 可以使用进度条增加用户体验度,此方法在主线程执行,用于显示任务的进度。
4)onPreExecute() 这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示对话框的进度。
5)onCancalled() 用户调用取消时要做的操作。

使用AsynTask必须遵守以下准则
1)AsynTask 的实例必须在UI Thread中创建
2)execute 方法必须在UI Thread中调用
3)不要手动调用doInBackground(Params…)、onPostExecute(Result)、onProgressUpdate(Progress…)这几个方法,该Task只能被调用执行一次,多次调用将会出现异常。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值