Android:Service完全解析(三)

来源:互联网 发布:flac mp3 mac 编辑:程序博客网 时间:2024/04/29 06:11

创建前台Service

Service几乎都是在后台运行的,一直以来它都是默默地做着辛苦的工作。但是Service的系统优先级还是比较低的,当系统出现内存不足情况时,就有可能会回收掉正在后台运行的Service。如果你希望Service可以一直保持运行状态,而不会由于系统内存不足的原因导致被回收,就可以考虑使用前台Service。前台Service和普通Service最大的区别就在于,它会一直有一个正在运行的图标在系统的状态栏显示,下拉状态栏后可以看到更加详细的信息,非常类似于通知的效果。当然有时候你也可能不仅仅是为了防止Service被回收才使用前台Service,有些项目由于特殊的需求会要求必须使用前台Service,比如说墨迹天气,它的Service在后台更新天气数据的同时,还会在系统状态栏一直显示当前天气的信息,如下图所示:

                                           

那么我们就来看一下如何才能创建一个前台Service吧,其实并不复杂,修改MyService中的代码,如下所示:

[java] view plaincopy
  1. public class MyService extends Service  
  2.   
  3.     public static final String TAG "MyService";  
  4.   
  5.     private MyBinder mBinder new MyBinder();  
  6.   
  7.     @Override  
  8.     public void onCreate()  
  9.         super.onCreate();  
  10.         Notification notification new Notification(R.drawable.ic_launcher,  
  11.                 "有通知到来", System.currentTimeMillis());  
  12.         Intent notificationIntent new Intent(this, MainActivity.class);  
  13.         PendingIntent pendingIntent PendingIntent.getActivity(this, 0,  
  14.                 notificationIntent, 0);  
  15.         notification.setLatestEventInfo(this, "这是通知的标题", "这是通知的内容",  
  16.                 pendingIntent);  
  17.         startForeground(1, notification);  
  18.         Log.d(TAG, "onCreate() executed");  
  19.      
  20.   
  21.     .........  
  22.   
  23.  
这里只是修改了MyService中onCreate()方法的代码。可以看到,我们首先创建了一个Notification对象,然后调用了它的setLatestEventInfo()方法来为通知初始化布局和数据,并在这里设置了点击通知后就打开MainActivity。然后调用startForeground()方法就可以让MyService变成一个前台Service,并会将通知的图片显示出来。

现在重新运行一下程序,并点击Start Service或BindService按钮,MyService就会以前台Service的模式启动了,并且在系统状态栏会弹出一个通栏图标,下拉状态栏后可以看到通知的详细内容,如下图所示。

                                           

在上篇文章中我们知道了,Service其实是运行在主线程里的,如果直接在Service中处理一些耗时的逻辑,就会导致程序ANR。

让我们来做个实验验证一下吧,修改上一篇文章中创建的ServiceTest项目,在MyService的onCreate()方法中让线程睡眠60秒,如下所示:

[java] view plaincopy
  1. public class MyService extends Service  
  2.   
  3.     ......  
  4.   
  5.     @Override  
  6.     public void onCreate()  
  7.         super.onCreate();  
  8.         Log.d(TAG, "onCreate() executed");  
  9.         try  
  10.             Thread.sleep(60000);  
  11.         catch (InterruptedException e)  
  12.             e.printStackTrace();  
  13.          
  14.      
  15.       
  16.     ......  
  17.   
  18.  

重新运行后,点击一下Start Service按钮或BindService按钮,程序就会阻塞住并无法进行任何其它操作,过一段时间后就会弹出ANR的提示框,如下图所示。

                                               

之前我们提到过,应该在Service中开启线程去执行耗时任务,这样就可以有效地避免ANR的出现。

那么本篇文章的主题是介绍远程Service的用法,如果将MyService转换成一个远程Service,还会不会有ANR的情况呢?让我们来动手尝试一下吧。

将一个普通的Service转换成远程Service其实非常简单,只需要在注册Service的时候将它的android:process属性指定成:remote就可以了,代码如下所示:

[html] view plaincopy
    0 0
    原创粉丝点击