安卓单线程模型

主线程(UI Thread)

  • 当Android应用程序启动时,系统会创建一个主线程(main thread).
  • 默认情况下,程序的操作都在这个主线程中进行,包括应用和用户界面UI的交互,所有main thread 也叫UI thread 也叫UI线程。

主线程阻塞

  • 因为所有的工资都在UI线程,当做一些比较好使的工作(比如访问网络或者数据库查询)就会阻塞UI线程。
  • 当UI线程被阻塞的时候,对于用户来说,应用程序看起来像是卡住了,更坏的情况是,如果UI线程阻塞的时间太长了(大约5秒),用户就会看到ANR(application not responding)的对话框
  • 因此,应该避免阻塞UI线程。

非UI线程:子线程(Worker Thread)

  • 要保证应用程序的响应性,不能阻塞UI线程,所有当操作不是即使操作,应该把它们放进另外的单线程中,(一般叫做background或者叫worker线程)。
  • 不能从非UI线程来操作UI组件

异步消息机制可以实现:

  • 线程之间发送消息
  • 线程之间传递数据

异步消息机制实现方法

  • Handler机制
  • AsyncTask异步任务
Handle异步消息机制实现
  • 同步调用:就是在一个函数或方法调用时,没有得到结果之前,该调用就不返回,直到返回结果。
  • 异步调用:在一个异步调用发起后,被调用者立即返回给调用者,但是调用者不能立刻得到结果,被调用都在实际处理这个调用的请求完成后,通过状态、通知或回调等方式来通知调用者请求处理的结果。
  • Handler提供了一种异步的线程操作方案以及异步消息处理机制,它可以把消息和Runnable对象发送到与Hanlder相关联的消息队列中。
  • 通俗来讲,就是用来在线程之间发送消息的处理对象。
  • 在任何线程中只要获得了另一个线程的Handle对象,就可以通过sendMessage(Messagemsg)方法向目标线程发送消息。
  • Android单线程模型
    • 不可以阻塞UI,在UI线程中执行耗时操作
    • 在飞UI线程不能操作UI组件
  • 新增一个子线程,子线程执行耗时操作后可以通过主线程的Handler向UI线程发送消息,有UI线程去更新界面。
  • Handler关联一个单独的线程,拥有线程的消息队列
  • 默认情况下,Handler和调用该Handler的线程关联
  • Handler可以接收、调度、派发、处理消息
  • 涉及到的核心类
    • Looper
      • 消息循环通道,Looper包含了一个Message Queue(消息队列)
      • 在使用Handler处理Massge时,需要Looper(通道)来完成
      • Looper不断的取出消息,交给Handler处理
  • Handler
    • 主要作用是消息处理
  • Message
    • 消息类,主要功能是进行消息的封装,封装了消息和处理改任务的Handler。

UI主线程的消息循环

  • 默认UI、
  • 主线程已经具备消息循环机制
  • 只需要为主线程创建一个Handler即可开始进行消息处理
  • 需要注意的是:非UI线程默认没有消息循环,需要通过Looper.prepare()和Looper.loop()为其建立消息循环。

主线程Handler使用的基本步骤

  • 在Activity中生成Handler对象uiHandler,并重写HandlerMessage方法。
  • 在主线程中启动子线程
  • 在子线程中创建消息,然后调用sendMessage方法想uiHandler发送消息。
  • 在uiHandler中handleMeaage会根据消息的不用进行相应的操作,如更新UI

关键代码:uiHandler创建

//创建uiHandler
private Handler uiHandler = new Handler(){
	
    @Override
    public void handleMessage(Message msg){
        super.handlerMessage(msg);
        //根据消息不同做不同的处理
        switch(msg.what){
            case 1:{
                //获取数据,并更新到UI
                bm = (Bitmap)msg.obj;
                previewImage();
                break;
            }
            case 0:{
                //提示用户数据获取失败
                Toast.makeText(DemoSetScreenHandle.this,"子线程获取数据失败",Toast.LENGTH_SHORT).show();
                break;
            }
        }
    }
};

关键代码:子线程创建消息并发送消息

class workThread extends Thread{
    @Override
    public void run(){
        super.run();
        try{
            //执行子线程任务,获取网络数据
            URL url = new URL("https://www.baidu.com/img/bd_logo1.png");
            URLConnection conn = url.openConection();
            Bitmap bmBitmap = BitmapFactory.decodeStream(conn.getInputStream());
            
            //创建消息
            Message newmsg = new Message();
            newmsg.what = 1;
            newmag.obj = bmBitmap;
            
            //发送消息
            uiHandler.sendMessage(newmag);
        }catch(Excrption e){
            Log.e(TAG,e.getMessage());
        }
    }
}

AsyncTask类的应用

Android为了降低这个开发难度,提供了AsyncTask。AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务。

AsyncTask直接继承于Object类,位置为android.os.AsyncTask .

AsyncTask定义了三种泛型类型 Params,Progress和Result。

· Params 启动任务执行的输入参数,比如HTTP请求的URL。

· Progress 后台任务执行的进度百分比。

· Result 后台执行任务最终返回的结果,比如String。

一个异步任务的执行一般包括以下几个步骤:

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组件上。

6.onCancelled() 用户调用取消时,要做的操作

Handler异步消息处理

Handler机制主要角色

n Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。

n Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。

n MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。

n Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。

n Thread:线程,负责调度整个消息循环,即消息循环的执行场所。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值