[Android每日精彩]Service增强

Q1.我们使用service来做哪些事儿?

Service是一个专门在后台处理长时间任务(比如网络查询,处理数据,更新Content Provider,firing Intents,和触发Notification)的Android组件,它没有UI。

Q1.1这里的后台指的是什么?

Android的后台就是指,它的运行是完全不依赖UI的,即使Activity被销毁,或者程序被关闭,只要
进程还在,Service就可以继续运行

Q1.2既然在Service里也要创建一个子线程,那为什么不直接在Activity里创建呢?

因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获
取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行
操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中
的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中
Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心
无法对后台任务进行控制的情况。

Q2.音乐播放器如何在后台一直播放?

Service组件的优先级比不活跃的Activity高,这样被系统杀死的概率就降低了。当然,实际上即便运行
中的Service被杀,但是当系统资源又足够的时候,Service又会被重启。
当必要的时候Service的优先级可能被提到与前台Activity相同的优先级(通过组件的标签)。这是极端
的例子,当结束掉Service会直接影响用户体验的时候,比如音乐的播放被打断。
尽管Service跑起来不需要UI,但是它仍然在UI线程中执行。所以有些耗时的操作你需要放在其他的工作
线程中,比如Thread和AsynTask类等

Q3.怎样使创建的Service只由自己的APP操纵

需要添加权限
<service android:enabled=”true” 
           android:name=”.MyService” 
           android:permission=”com.paad.MY_SERVICE_PERMISSION”/>

Q4. onStartCommand返回参数的作用?

返回的参数是用来决定当系统在Service运行时杀死了Service,资源足够的时候又重启这个Service,
系统该如何回应的。
START_STICKY:如果返回的是这个值,当Service任何时候的重启,onStartCommand都会被调用。
但是注意的一点:传来的intent参数会丢失,也就是null。
START_NOT_STICKY:当运行时被杀死的时候,如果之前还有start请求未处理(注意是未处理,而
不是处理中),Service才会被重启,否则服务自动停止
START_REDELIVER_INTENT:如果Service在运行中被杀死,如果还有请求未被处理,或者在处理中。
在后者情况,onStartCommand会被调用,传入之前传入的初始状态的Intent,因为它认为还没有
完全处理好。

注意:以上行为只有在System kill event的情况下有效,stopSelf和stopService都不会过问
onStartCommand的返回状态

下面2个参数是用来判断你的Service是怎么启动的:
1.START_FLAG_REDELIVERY  对应着START_REDELIVER_INTENT
2.START_FLAG_RETRY 对应着START_STICKY

Q5.如何进行绑定service?

调用bindService。传入一个intent(隐式或者显式)和ServiceConnection的实例
Intent bindIntent = new Intent(MyActivity.this, MyMusicService.class);
bindService(bindIntent, mConnection, Context.BIND_AUTO_CREATE);
你还需要去实现一个ServiceConnection,重写它的onServiceConnected和
onServiceDisconneted方法去获取一个Service实例的引用。
// Reference to the service 
private MyMusicService serviceRef;

// Handles the connection between the service and activity 
private ServiceConnection mConnection = new ServiceConnection() { 
        public void onServiceConnected(ComponentName className, 
                                              IBinder service) { 
           // Called when the connection is made. 
           serviceRef = ((MyMusicService.MyBinder)service).getService(); 
        }

        public void onServiceDisconnected(ComponentName className) { 
           // Received when the service unexpectedly disconnects. 
           serviceRef = null; 
        } 
};

Q6.如何创建前台Service?

Service几乎都是在后台运行的,一直以来它都是默默地做着辛苦的工作。但是Service的系统优先级
还是比较低的,当系统出现内存不足情况时,就有可能会回收掉正在后台运行的Service。如果你希望
Service可以一直保持运行状态,而不会由于系统内存不足的原因导致被回收,就可以考虑使用前台
Service。前台Service和普通Service最大的区别就在于,它会一直有一个正在运行的图标在系统
的状态栏显示,下拉状态栏后可以看到更加详细的信息,非常类似于通知的效果。当然有时候你也可能
不仅仅是为了防止Service被回收才使用前台Service,有些项目由于特殊的需求会要求必须使用前台
Service,比如说墨迹天气,它的Service在后台更新天气数据的同时,还会在系统状态栏一直显示
当前天气的信息,如下图所示:
foreground_service.png
在进程优先级中,正在运行的Service优先级是老二的位置,仅次与运行在前台的Activity。
如果你的Service直接可以与用户交互的,那么考虑将其放在前台是必要的。通过startForeground.
startForeground通常必须指定一个不间断的Notification。这个Notification存在的时间与
你的跑在前台的Service相同
private void startPlayback(String album, String artist) { 
              int NOTIFICATION_ID = 1;

              // Create an Intent that will open the main Activity 
              // if the notification is clicked. 
              Intent intent = new Intent(this, MyActivity.class); 
              PendingIntent pi = PendingIntent.getActivity(this, 1, intent, 0);

              // Set the Notification UI parameters 
              Notification notification = new Notification(R.drawable.icon, 
                “Starting Playback”, System.currentTimeMillis()); 
              notification.setLatestEventInfo(this, album, artist, pi);

              // Set the Notification as ongoing 
              notification.flags = notification.flags | 
                                        Notification.FLAG_ONGOING_EVENT;

              // Move the Service to the Foreground 
              startForeground(NOTIFICATION_ID, notification);  
}
结束前台的Service通过stopForeground,Notification也会被取消:
public void pausePlayback() { 
        // Move to the background and remove the Notification 
        stopForeground(true); 
}

Q7.关于远程service。如果将普通Service转换成一个远程Service,在onCreate中执行,还会不会有ANR的情况呢?

将一个普通的Service转换成远程Service其实非常简单,只需要在注册Service的时候将
它的android:process属性指定成:remote就可以了
    <service  
        android:name="com.example.servicetest.MyService"  
        android:process=":remote" >  
    </service>  
不会导致ANR,因为使用了远程Service后,MyService已经在另外一个进程当中运行了,所以
只会阻塞该进程中的主线程,并不会影响到当前的应用程序

Q7.1那既然远程Service这么好用,干脆以后我们把所有的Service都转换成远程Service吧,还省得再开启线程了?

远程Service非但不好用,甚至可以称得上是较为难用。一般情况下如果可以不使用远程Service,
就尽量不要使用它。在使用Start Service方式开启远程service不会崩溃,但是使用bindservice
方式会崩溃。这是由于用Bind Service我们会让MainActivity和MyService建立关联,但是目前MyService已经是一个远程Service了,Activity和Service运行在两个不同的进程当中,这时就不能再使用传统的建立关联的方式,程序也就崩溃了。

Q7.2如何才能让Activity与一个远程Service建立关联呢?

有办法,使用AIDL来进行跨进程通信
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容