后台服务(九)

       后台服务安全

1.在子线程中更新 UI是一种不安全的行为,必须在主线程中进行,不然就会出现异常。可以使用Handler类方法进行替换异步


      解析异步消息处理机制
1.  Message
 Message是在线程之间传递的消息,它能够在内部携带少许的信息,用于在不一样线
 程之间交换数据。上一小节中咱们使用到了 Message 的 what 字段,除此以外还可使
 用 arg1和 arg2字段来携带一些整型数据,使用 obj字段携带一个 Object对象。
2.  Handler
 Handler 顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消
 息通常是使用 Handler 的 sendMessage()方法,而发出的消息通过一系列地展转处理后,
 最终会传递到 Handler 的 handleMessage()方法中。
3.  MessageQueue
 MessageQueue 是消息队列的意思,它主要用于存放全部经过 Handler 发送的消息。
 这部分消息会一直存在于消息队列中, 等待被处理。 每一个线程中只会有一个 MessageQueue
 对象。
4.  Looper
 Looper 是每一个线程中的 MessageQueue 的管家,调用 Looper 的 loop()方法后,就会
 进入到一个无限循环当中,而后每当发现 MessageQueue 中存在一条消息,就会将它取
 出, 并传递到 Handler的 handleMessage()方法中。 每一个线程中也只会有一个 Looper 对象。oop

流程说明:首先须要在主线程当中建立一个 Handler 对象,并重写
 handleMessage()方法。而后当子线程中须要进行 UI 操做时,就建立一个 Message 对象,并
 经过 Handler 将这条消息发送出去。以后这条消息会被添加到 MessageQueue 的队列中等待
 被处理,而 Looper 则会一直尝试从 MessageQueue 中取出待处理消息,最后分发回 Handler
 的 handleMessage()方法中。this

     使用 AsyncTask:
泛型参数:
 1.  Params
  在执行 AsyncTask时须要传入的参数,可用于在后台任务中使用。
 2.  Progress
  后台任务执行时,若是须要在界面上显示当前的进度,则使用这里指定的泛型做为进度单位。
 3.  Result
  当任务执行完毕后,若是须要对结果进行返回,则使用这里指定的泛型做为返回值类型。 线程

重写方法:
 1.  onPreExecute()
  这个方法会在后台任务开始执行以前调用,用于进行一些界面上的初始化操做,比
  如显示一个进度条对话框等。
 2.  doInBackground(Params...)
  这个方法中的全部代码都会在子线程中运行, 咱们应该在这里去处理全部的耗时任
  务。任务一旦完成就能够经过 return 语句来将任务的执行结果返回,若是 AsyncTask的
  第三个泛型参数指定的是 Void,就能够不返回任务执行结果。注意,在这个方法中是不
  能够进行 UI操做的,若是须要更新 UI元素,好比说反馈当前任务的执行进度,能够调
  用 publishProgress(Progress...)方法来完成。
 3.  onProgressUpdate(Progress...)
  当在后台任务中调用了 publishProgress(Progress...)方法后,这个方法就会很快被调
  用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中能够对 UI 进行操
  做,利用参数中的数值就能够对界面元素进行相应地更新。
 4.  onPostExecute(Result)
  当后台任务执行完毕并经过 return语句进行返回时,这个方法就很快会被调用。返
  回的数据会做为参数传递到此方法中,能够利用返回的数据来进行一些 UI 操做,好比
  说提醒任务执行的结果,以及关闭掉进度条对话框等。对象

 

    服务的基本用法
1.定义一个服务:
 1.继承 Service
 2.重写了 onCreate()方法会在服务建立的时候调用、onStartCommand()方法会在每次服务启动的时候调用
 和 onDestroy()方法会在服务销毁的时候调用
 3.onBind(Intent i) 中具体的操做或者返回具体的操做类
 4.建立一个服务链接池。ServiceConnection onServiceConnected活动被绑定  onServiceDisconnected解除绑定
 5.经过这种方式启动、关闭、绑定、解除绑定服务。
  Intent startIntent = new Intent(this, MyService.class);
                startService(startIntent); / stopService(stopIntent);  bindService(bindIntent, serviceConnection, BIND_AUTO_CREATE);     unbindService(serviceConnection);  继承

      服务的生命周期
 服务也有本身的生命周期,前面咱们使用到的 onCreate()、onStartCommand()、onBind()和 onDestroy()等方法都是在服务的生命周期内可能回调的方法。
 一旦在项目的任何位置调用了 Context的 startService()方法,相应的服务就会启动起来,并回调 onStartCommand()方法。若是这个服务以前尚未建立过,onCreate()方法会先于onStartCommand()方法执行。服务启动了以后会一直保持运行状态,直到 stopService()或stopSelf()方法被调用。注意虽然每调用一次 startService()方法,onStartCommand()就会执行一次, 但实际上每一个服务都只会存在一个实例。 因此无论你调用了多少次 startService()方法,只需调用一次 stopService()或 stopSelf()方法,服务就会中止下来了。
 另外,还能够调用 Context 的 bindService()来获取一个服务的持久链接,这时就会回调服务中的 onBind()方法。相似地,若是这个服务以前尚未建立过,onCreate()方法会先于onBind()方法执行。以后,调用方能够获取到 onBind()方法里返回的 IBinder对象的实例,这样就能自由地和服务进行通讯了。只要调用方和服务之间的链接没有断开,服务就会一直保持运行状态。
 当调用了 startService()方法后,又去调用 stopService()方法,这时服务中的 onDestroy()方法就会执行,表示服务已经销毁了。相似地,当调用了 bindService()方法后,又去调用unbindService()方法,onDestroy()方法也会执行,这两种状况都很好理解。可是须要注意,咱们是彻底有可能对一个服务既调用了 startService()方法,又调用了 bindService()方法的,这种状况下该如何才能让服务销毁掉呢?根据 Android 系统的机制,一个服务只要被启动或者被绑定了以后,就会一直处于运行状态,必需要让以上两种条件同时不知足,服务才能被销毁。因此,这种状况下要同时调用 stopService()和 unbindService()方法,onDestroy()方法才会执行。生命周期

 

      前台服务
1.实现原理:在Service服务的onCreate方法中,经过通知的方式在前台状态中显示队列

 

      定时任务
1.Timer类:Timer有一个明显的短板,它并不太适用于那些须要长期在后台运行的定时任务。咱们都知道,为了能让电池更加耐用,每种手机都会有本身的休眠策略,Android 手机就会在长时间不操做的状况下自动让 CPU 进入到睡眠状态,这就有可能致使 Timer中的定时任务没法正运行。消息队列

2.Alarm机制: AlarmManager的工做类型
 1. ELAPSED_REALTIME 表示让定时任务的触发时间从系统开机开始算起,但不会唤醒 CPU
 2.ELAPSED_REALTIME_WAKEUP 表示让定时任务的触发时间从系统开机开始算起,但会唤醒 CPU
 3.RTC 表示让定时任务的触发时间从 1970 年 1月 1日 0 点开始算起,但不会唤醒 CPU
 4.RTC_WAKEUP 表示让定时任务的触发时间从1970 年 1月 1 日 0 点开始算起,但会唤醒 CPU
 使用 SystemClock.elapsedRealtime()方法能够获取到系统开机至今所经历时间的毫秒数
 使用 System.currentTimeMillis()方法能够获取到 1970年 1月 1 日 0点至今所经历时间的毫秒数

相关文章
相关标签/搜索