阅读时有疑惑的地方:

  1. 继承IntentService类,它本身提供了一个工作者进程,可以接收onStartCommond发送过来的请求,关键是这句话“Stops the service after all start requests have been handled, so you never have to call stopSelf()”,意思是它在所有请求都被处理以后,也就是被onHandleIntent()处理以后,自己就会关闭。是不是说,发送了一个请求,处理了以后,它就关闭了?还是说,非得同时发送了多个请求,或者在onHandlerIntent的处理过程中也持续不断的有请求过来,当这段处理都过去以后,它就自己关掉了?那这样不是一次性的服务吗?万一想隔十分钟调用一次Service,而处理只是一瞬间,那是不可以理解成每次调用,都是重新启动的它。
  2. 停止服务,stopService和stopSelf方法,为了保证当前关闭时,没有新的请求过来导致误关,SDK建议用stopSelf方法来关闭,该方法有一个id的参数,id是onStartCommon的请求ID,这样能够保证关掉的是最后。但是这个id要怎么和stopSelf方法结合起来用呢?是说每次在onStartCommond调用的时候,把最新这一次的startId先放在全局变量里面,然后在其他地方,比如onStartCommond处理完了以后,再调用stopSelf(startId)方法来结束Service。它这时候是不是把这个startId和Service本身生成的最新startId比较,若相同,就可以结束掉Service,否则,就不结束。也就是说,只要有一次请求,不管有没有在Service里面执行,都会相应的生成一个startId。这样就能保证在request没有全部被处理时,无法结束Service.
  3. 要单独处理的话,为啥不直接用线程,而要用Service?


主要包括以下三个方面:

  1. service概况
  2. 如何创建service
  3. 生命周期

一、Service概况

  Service是一个可以执行后台操作的应用程序组件,主要是用来执行一些后台的耗时操作,常见比如请求网络、播放音乐、读取文件、读取数据库等。它没有自己的线程,是运行在主线程里面的,也即和UI的那个线程是一样的,因而,在Service里面,一定要记得新起一个线程来做自己想要做的操作。Service主要分成两类:

  1. Service 常规的Service
  2. bindService 绑定方式创建的Service

  区别主要是调用方式不一样,常规的通过startService方法来调用,触发onStartCommond()方法,需要在Service中控制它的结束或者在客户端调用结束的方法来结束;而bindService通过bindService方法来调用,触发onBind()方法,当所有bind的client都unBlind后,会由系统来自动结束掉。

  运行在后台的Service可以被系统给杀掉,而标记为foreground的Service则不可以。在AndroidManifest.xml中的Service节点,定义时,也可以把Service定义成是否允许其它应用程序访问(android:exported属性),以及定义自己的intent filter接受请求。

二、创建Service

  创建常规的Service主要有两种方式:

  1. 继承Service类。需要自己负责处理从onStartCommond()方法接收到的多个请求,可以针对每个请求单独开一个线程来并行处理;
    package com.example.android.apistudy.service;
    
    
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.os.IBinder;
    import android.os.Looper;
    import android.os.Message;
    import android.os.Process;
    import android.support.v4.app.NotificationCompat;
    
    import com.example.android.apistudy.project.R;
    import com.example.android.apistudy.project.ShowInfoActivity;
    
    public class BackGroundService extends Service {
    
        private ServiceHandler mHandler;
        @Override
        public void onCreate(){
            HandlerThread thread=new HandlerThread("mythread",Process.THREAD_PRIORITY_BACKGROUND);
            thread.start();
            
            Looper looper=thread.getLooper();
            mHandler=new ServiceHandler(looper);
            
        }
        @Override
        public int onStartCommand(Intent intent,int flags,int startId){
            Message msg=new Message();
            mHandler.sendMessage(msg);
            return START_STICKY; 
        }
        
        @Override
        public IBinder onBind(Intent arg0) {
            // TODO Auto-generated method stub
            return null;
        }
        @Override
        public void onDestroy(){
            Message msg=new Message();
            mHandler.sendMessage(msg);
        }
        
        private final class ServiceHandler extends Handler{
            
            
            public ServiceHandler(Looper looper){
                super(looper);
            }
            
            
            @Override
            public void handleMessage(Message msg){
                NotificationCompat.Builder mBuilder=new NotificationCompat.Builder(getApplicationContext());
                mBuilder.setSmallIcon(R.drawable.ic_launcher);
                mBuilder.setContentTitle("Title::::");
                mBuilder.setContentText("content......");
                
                PendingIntent pendingIntent=PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(),ShowInfoActivity.class), 0);
                mBuilder.setContentIntent(pendingIntent);
                
                NotificationManager manager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
                manager.notify(0, mBuilder.build());
            }
        }
        
        
    }
  2. 继承IntentService类。实现了一个工作者线程,用来管理所有发送过来的请求,并且触发onHandleIntent()方法来处理,但是不适用于请求同时并发的情况,适合一次性的请求操作。
package com.example.android.apistudy.service;


import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.support.v4.app.NotificationCompat;

import com.example.android.apistudy.project.R;
import com.example.android.apistudy.project.ShowInfoActivity;

public class BackGroundIntentService extends IntentService {

    public BackGroundIntentService() {
        super("backgroundIntentService");
        // TODO Auto-generated constructor stub
    }

    

    @Override
    protected void onHandleIntent(Intent intent) {
        NotificationCompat.Builder mBuilder=new NotificationCompat.Builder(getApplicationContext());
        mBuilder.setSmallIcon(R.drawable.ic_launcher);
        mBuilder.setContentTitle("Title::::");
        mBuilder.setContentText("content......");
        
        PendingIntent pendingIntent=PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(),ShowInfoActivity.class), 0);
        mBuilder.setContentIntent(pendingIntent);
        
        NotificationManager manager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        manager.notify(0, mBuilder.build());
    }
}

    这个通知不会在点了一下以后消失,只有当Service停止以后才会消失。

 

三、生命周期

   借用下SDK里面的生命周期图:

    两种创建Service的方式,对应于不同的生命周期。木有onStop回调函数,Service销毁以后,都是触发onDestroy方法。同时,普通的Service也可以通过bind的方式来访问。是否一旦使用bind方式以后,Service就不能被人为给停止掉。

  onStartCommond()方法有三个返回值:

  •  START_NOT_STICKY ,当service被系统给杀掉以后,不会重新创建Service,直到下一次有新的请求过来;
  •  START_STICKY,当Service被系统给杀掉以后,重新创建Service,但是传递进来的intent对象是空值,并不是之前传递过的; 
  •  START_REDELIVER_INTENT,当Service被系统给杀掉以后,重新创建Service,传递进来的intent对象是之前最新一次传递的Intent,适合下载文件的时候使用。 
posted on 2013-01-28 14:54  西瓜瓜瓜瓜瓜  阅读(387)  评论(0编辑  收藏  举报