Android总结篇系列:Android Service

Service一般老是称之为“后台服务”,其中“后台”一词是相对于前台而言的,具体是指其自己的运行并不依赖于用户可视的UI界面,所以,从实际业务需求上来理解,Service的适用场景应该具有如下条件:android

1.并不依赖于用户可视的UI界面(固然,这一条其实也不是绝对的,如前台Service就是与Notification界面结合使用的);微信

2.具备较长时间的运行特性。多线程

1.Service AndroidManifest.xml 声明并发

通常而言,从Service的启动方式上,能够将Service分为Started Service和Bound Service。不管哪一种具体的Service启动类型,都是经过继承Service基类自定义而来。在使用Service时,要想系统可以找到此自定义Service,不管哪一种类型,都须要在AndroidManifest.xml中声明,语法格式以下:ide

 1 <service android:enabled=["true" | "false"]  2  android:exported=["true" | "false"]  3  android:icon="drawable resource"
 4  android:isolatedProcess=["true" | "false"]  5  android:label="string resource"
 6  android:name="string"
 7  android:permission="string"
 8  android:process="string" >
 9  . . . 10 </service>

其中,android:exported属性上一篇博文中对此已进行详尽描述,android:name对应Service类名,android:permission是权限声明,android:process设置具体的进程名称。须要注意的是Service可否单独使用一个进程与其启动方式有关,本后下面会给出具体说明。其余的属性此处与其余组件基本相同,再也不过多描述。函数

注:若是自定义Service没有在AndroidManifest.xml中声明,当具体使用时,不会像Activity那样直接崩溃报错,对于显式Intent启动的Service,此时也会给出waring信息“IllegalArgumentException: Service not registered”,有时候不容易发现忘了声明而一时定位不到问题。post

 

2.Started Servicethis

 Started Service相对比较简单,经过context.startService(Intent serviceIntent)启动Service,context.stopService(Intent serviceIntent)中止此Service。固然,在Service内部,也能够经过stopSelf(...)方式中止其自己。spa

1)Started Service自定义线程

下面代码片断显示的是一个最基本的Started Service的自定义方式:

 1 public class MyService extends Service {  2 
 3     public static final String TAG = "MyService";  4 
 5  @Override  6     public IBinder onBind(Intent intent) {  7         return null;  8  }  9 
10  @Override 11     public void onCreate() { 12         super.onCreate(); 13         Log.w(TAG, "in onCreate"); 14  } 15 
16  @Override 17     public int onStartCommand(Intent intent, int flags, int startId) { 18         Log.w(TAG, "in onStartCommand"); 19         Log.w(TAG, "MyService:" + this); 20         String name = intent.getStringExtra("name"); 21         Log.w(TAG, "name:" + name); 22         return START_STICKY; 23  } 24 
25  @Override 26     public void onDestroy() { 27         super.onDestroy(); 28         Log.w(TAG, "in onDestroy"); 29  } 30 }

其中,onBind(...)函数是Service基类中的惟一抽象方法,子类都必须重写实现,此函数的返回值是针对Bound Service类型的Service才有用的,在Started Service类型中,此函数直接返回 null 便可。onCreate(...)、onStartCommand(...)和onDestroy()都是Started Service相应生命周期阶段的回调函数。

2) Started Service使用

 1 public class MainActivity extends Activity {  2 
 3     public static final String TAG = "MainActivity";  4 
 5     private Button startServiceBtn;  6     private Button stopServideBtn;  7     private Button goBtn;  8 
 9     private Intent serviceIntent; 10 
11  @Override 12     protected void onCreate(Bundle savedInstanceState) { 13         super.onCreate(savedInstanceState); 14  setContentView(R.layout.activity_main); 15 
16         startServiceBtn = (Button) findViewById(R.id.start_service); 17         stopServideBtn = (Button) findViewById(R.id.stop_service); 18         goBtn = (Button) findViewById(R.id.go); 19 
20         startServiceBtn.setOnClickListener(new View.OnClickListener() { 21  @Override 22             public void onClick(View v) { 23                 serviceIntent = new Intent(MainActivity.this, MyService.class); 24  startService(serviceIntent); 25  } 26  }); 27 
28         stopServideBtn.setOnClickListener(new View.OnClickListener() { 29  @Override 30             public void onClick(View v) { 31  stopService(serviceIntent); 32  } 33  }); 34 
35         goBtn.setOnClickListener(new View.OnClickListener() { 36  @Override 37             public void onClick(View v) { 38                 Intent intent = new Intent(MainActivity.this, BActivity.class); 39  startActivity(intent); 40  } 41  }); 42 
43  } 44 
45  @Override 46     protected void onDestroy() { 47         super.onDestroy(); 48         Log.w(TAG, "in onDestroy"); 49  } 50 }

如上代码片断,

当Client调用startService(Intent serviceIntent)后,若是MyService是第一次启动,首先会执行 onCreate()回调,而后再执行onStartCommand(Intent intent, int flags, int startId),当Client再次调用startService(Intent serviceIntent),将只执行onStartCommand(Intent intent, int flags, int startId),由于此时Service已经建立了,无需执行onCreate()回调。不管多少次的startService,只须要一次stopService()便可将此Service终止,执行onDestroy()函数(其实很好理解,由于onDestroy()与onCreate()回调是相对的)。

下面重点关注下onStartCommand(Intent intent, int flags, int startId)方法。

其中参数flags默认状况下是0,对应的常量名为START_STICKY_COMPATIBILITY。startId是一个惟一的整型,用于表示这次Client执行startService(...)的请求请求标识,在屡次startService(...)的状况下,呈现0,1,2....递增。另外,此函数具备一个int型的返回值,具体的可选值及含义以下:

START_NOT_STICKY:当Service由于内存不足而被系统kill后,接下来将来的某个时间内,即便系统内存足够可用,系统也不会尝试从新建立此Service。除非程序中Client明确再次调用startService(...)启动此Service。

START_STICKY:当Service由于内存不足而被系统kill后,接下来将来的某个时间内,当系统内存足够可用的状况下,系统将会尝试从新建立此Service,一旦建立成功后将回调onStartCommand(...)方法,但其中的Intent将是null,pendingintent除外。

START_REDELIVER_INTENT:与START_STICKY惟一不一样的是,回调onStartCommand(...)方法时,其中的Intent将是非空,将是最后一次调用startService(...)中的intent。

START_STICKY_COMPATIBILITY:compatibility version of {@link #START_STICKY} that does not guarantee that {@link #onStartCommand} will be called again after being killed。此值通常不会使用,因此注意前面三种情形就好。

以上的描述中,”当Service由于内存不足而被系统kill后“必定要很是注意,由于此函数的返回值设定只是针对此种状况才有意义的,换言之,当认为的kill掉Service进程,此函数返回值不管怎么设定,接下来将来的某个时间内,即便系统内存足够可用,Service也不会重启。

小米手机针对此处作了变动:

另外,须要注意的是,小米手机针对此处作了必定的修改。在“自启动管理”中有一个自启动应用列表,默认状况下,只有少应用(如微信、QQ、YY、360等)默认是能够自启动的,其余应用默认都是禁止的。用户能够手动添加自启动应用,添加后的应用中若是Started Service onStartCommand(...)回调返回值是START_STICKY或START_REDELIVER_INTENT,当用户在小米手机上长按Home键结束App后,接下来将来的某个时间内,当系统内存足够可用时,Service依然能够按照上述规定重启。固然,若是用户在 设置 >> 应用 >> 强制kill掉App进程,此时Service是不会重启的。

注:以上实验结论基于小米2S亲测。

 

3) Started Service生命周期及进程相关

1.onCreate(Client首次startService(..)) >> onStartCommand >> onStartCommand - optional ... >> onDestroy(Client调用stopService(..))

注:onStartCommand(..)能够屡次被调用,onDestroy()与onCreate()想匹配,当用户强制kill掉进程时,onDestroy()是不会执行的。

2.对于同一类型的Service,Service实例一次永远只存在一个,而无论Client是不是相同的组件,也无论Client是否处于相同的进程中。

3.Service经过startService(..)启动Service后,此时Service的生命周期与Client自己的什么周期是没有任何关系的,只有Client调用stopService(..)或Service自己调用stopSelf(..)才能中止此Service。固然,当用户强制kill掉Service进程或系统因内存不足也可能kill掉此Service。

4.Client A 经过startService(..)启动Service后,能够在其余Client(如Client B、Client C)经过调用stopService(..)结束此Service。

5.Client调用stopService(..)时,若是当前Service没有启动,也不会出现任何报错或问题,也就是说,stopService(..)无需作当前Service是否有效的判断。

6.startService(Intent serviceIntent),其中的intent既能够是显式Intent,也能够是隐式Intent,当Client与Service同处于一个App时,通常推荐使用显示Intent。当处于不一样App时,只能使用隐式Intent。

当Service须要运行在单独的进程中,AndroidManifest.xml声明时须要经过android:process指明此进程名称,当此Service须要对其余App开放时,android:exported属性值须要设置为true(固然,在有intent-filter时默认值就是true)。

1 <service 2     android:name=".MyService"
3  android:exported="true"
4  android:process=":MyCorn" >
5     <intent-filter>
6         <action android:name="com.example.androidtest.myservice" />
7     </intent-filter>
8 </service>

 

4)Started Service Client与Service通讯相关

当Client调用startService(Intent serviceIntent)启动Service时,Client能够将参数经过Intent直接传递给Service。Service执行过程当中,若是须要将参数传递给Client,通常能够经过借助于发送广播的方式(此时,Client须要注册此广播)。

 

3.Bound Service

相对于Started Service,Bound Service具备更多的知识点。Bound Service的主要特性在于Service的生命周期是依附于Client的生命周期的,当Client不存在时,Bound Service将执行onDestroy,同时经过Service中的Binder对象能够较为方便进行Client-Service通讯。Bound Service通常使用过程以下:

1.自定义Service继承基类Service,并重写onBind(Intent intent)方法,此方法中须要返回具体的Binder对象;

2.Client经过实现ServiceConnection接口来自定义ServiceConnection,并经过bindService (Intent service, ServiceConnection sc, int flags)方法将Service绑定到此Client上;

3.自定义的ServiceConnection中实现onServiceConnected(ComponentName name, IBinder binder)方法,获取Service端Binder实例;

4.经过获取的Binder实例进行Service端其余公共方法的调用,以完成Client-Service通讯;

5.当Client在恰当的生命周期(如onDestroy等)时,此时须要解绑以前已经绑定的Service,经过调用函数unbindService(ServiceConnection sc)。

 在Bound Service具体使用过程当中,根据onBind(Intent intent)方法放回的Binder对象的定义方式不一样,又能够将其分为如下三种方式,且每种方式具备不一样的特色和适用场景:

1).Extending the Binder class

 这是Bound Service中最多见的一种使用方式,也是Bound Service中最简单的一种。

局限:Clinet与Service必须同属于同一个进程,不能实现进程间通讯(IPC)。不然则会出现相似于“android.os.BinderProxy cannot be cast to xxx”错误。

下面经过代码片断看下具体的使用:

 1 public class MyBindService extends Service {  2 
 3     public static final String TAG = "MyBindService";  4 
 5     private MyBinder mBinder = new MyBinder();  6 
 7     public class MyBinder extends Binder {  8  MyBindService getService() {  9             return MyBindService.this; 10  } 11  } 12 
13  @Override 14     public void onCreate() { 15         super.onCreate(); 16         Log.w(TAG, "in onCreate"); 17  } 18 
19  @Override 20     public IBinder onBind(Intent intent) { 21         Log.w(TAG, "in onBind"); 22         return mBinder; 23  } 24 
25  @Override 26     public boolean onUnbind(Intent intent) { 27         Log.w(TAG, "in onUnbind"); 28         return super.onUnbind(intent); 29  } 30 
31  @Override 32     public void onDestroy() { 33         super.onDestroy(); 34         Log.w(TAG, "in onDestroy"); 35  } 36 }
 1 public class BActivity extends Activity {  2 
 3     public static final String TAG = "BActivity";  4 
 5     private Button bindServiceBtn;  6     private Button unbindServiceBtn;  7 
 8     private Button startIntentService;  9 
10     private Intent serviceIntent; 11 
12     private ServiceConnection sc = new MyServiceConnection(); 13     private MyBinder mBinder; 14     private MyBindService mBindService; 15     private boolean mBound; 16 
17     private class MyServiceConnection implements ServiceConnection { 18 
19  @Override 20         public void onServiceConnected(ComponentName name, IBinder binder) { 21             Log.w(TAG, "in MyServiceConnection onServiceConnected"); 22             mBinder = (MyBinder) binder; 23             mBindService = mBinder.getService(); 24 
25             mBound = true; 26  } 27 
28  @Override 29         public void onServiceDisconnected(ComponentName name) { 30             // This is called when the connection with the service has been 31             // unexpectedly disconnected -- that is, its process crashed.
32             Log.w(TAG, "in MyServiceConnection onServiceDisconnected"); 33             mBound = false; 34  } 35 
36  } 37 
38  @Override 39     protected void onCreate(Bundle savedInstanceState) { 40         super.onCreate(savedInstanceState); 41  setContentView(R.layout.b); 42 
43         bindServiceBtn = (Button) findViewById(R.id.bind_service); 44         unbindServiceBtn = (Button) findViewById(R.id.unbind_service); 45         startIntentService = (Button) findViewById(R.id.start_intentservice); 46 
47         bindServiceBtn.setOnClickListener(new View.OnClickListener() { 48  @Override 49             public void onClick(View v) { 50                 Intent intent = new Intent(BActivity.this, MyBindService.class); 51  bindService(intent, sc, Context.BIND_AUTO_CREATE); 52  } 53  }); 54 
55         unbindServiceBtn.setOnClickListener(new View.OnClickListener() { 56  @Override 57             public void onClick(View v) { 58  excuteUnbindService(); 59  } 60  }); 61 
62         startIntentService.setOnClickListener(new View.OnClickListener() { 63  @Override 64             public void onClick(View v) { 65                 Intent intent = new Intent(BActivity.this, MyIntentService.class); 66  startService(intent); 67  } 68  }); 69 
70  } 71 
72     private void excuteUnbindService() { 73         if (mBound) { 74  unbindService(sc); 75             mBound = false; 76  } 77  } 78 
79  @Override 80     protected void onDestroy() { 81         super.onDestroy(); 82         Log.w(TAG, "in onDestroy"); 83  excuteUnbindService(); 84  } 85 }

首次点击bindServiceBtn进行bindService(..)时,依次回调顺序以下:

1 MyBindService(13457): in onCreate 2 MyBindService(13457): in onBind 3 BActivity(13457): in MyServiceConnection onServiceConnected

再次点击bindServiceBtn按钮时,发现没有任何输出,说明MyBindService没有进行任何回调。

点击unbindServiceBtn进行unbindService(..)时,回调顺序为:

1 MyBindService(13457): in onUnbind 2 MyBindService(13457): in onDestroy

 注:在四大基本组件中,须要注意的的是BroadcastReceiver不能做为Bound Service的Client,由于BroadcastReceiver的生命周期很短,当执行完onReceive(..)回调时,BroadcastReceiver生命周期完结。而Bound Service又与Client自己的生命周期相关,所以,Android中不容许BroadcastReceiver去bindService(..),当有此类需求时,能够考虑经过startService(..)替代。

 

2)Using a Messenger

Messenger,在此能够理解成”信使“,经过Messenger方式返回Binder对象能够不用考虑Clinet - Service是否属于同一个进程的问题,而且,能够实现Client - Service之间的双向通讯。极大方便了此类业务需求的实现。

局限:不支持严格意义上的多线程并发处理,其实是以队列去处理

下面直接看下具体的使用:

 1 public class MyMessengerService extends Service {  2 
 3     public static final String TAG = "MyMessengerService";  4 
 5     public static final int MSG_FROM_CLIENT_TO_SERVER = 1;  6     public static final int MSG_FROM_SERVER_TO_CLIENT = 2;  7 
 8     private Messenger mClientMessenger;  9     private Messenger mServerMessenger = new Messenger(new ServerHandler()); 10 
11  @Override 12     public IBinder onBind(Intent intent) { 13         Log.w(TAG, "in onBind"); 14         return mServerMessenger.getBinder(); 15  } 16 
17     class ServerHandler extends Handler { 18  @Override 19         public void handleMessage(Message msg) { 20             Log.w(TAG, "thread name:" + Thread.currentThread().getName()); 21             switch (msg.what) { 22             case MSG_FROM_CLIENT_TO_SERVER: 23                 Log.w(TAG, "receive msg from client"); 24                 mClientMessenger = msg.replyTo; 25 
26                 // service发送消息给client
27                 Message toClientMsg = Message.obtain(null, MSG_FROM_SERVER_TO_CLIENT); 28                 try { 29                     Log.w(TAG, "server begin send msg to client"); 30  mClientMessenger.send(toClientMsg); 31                 } catch (RemoteException e) { 32  e.printStackTrace(); 33  } 34                 break; 35             default: 36                 super.handleMessage(msg); 37  } 38  } 39  } 40 
41  @Override 42     public boolean onUnbind(Intent intent) { 43         Log.w(TAG, "in onUnbind"); 44         return super.onUnbind(intent); 45  } 46 
47  @Override 48     public void onDestroy() { 49         Log.w(TAG, "in onDestroy"); 50         super.onDestroy(); 51  } 52 }
 1 public class CActivity extends Activity {  2 
 3     public static final String TAG = "CActivity";  4 
 5     private Button bindServiceBtn;  6     private Button unbindServiceBtn;  7     private Button sendMsgToServerBtn;  8 
 9     private ServiceConnection sc = new MyServiceConnection();  10     private boolean mBound;  11 
 12     private Messenger mServerMessenger;  13 
 14     private Handler mClientHandler = new MyClientHandler();  15     private Messenger mClientMessenger = new Messenger(mClientHandler);  16 
 17     private class MyClientHandler extends Handler {  18  @Override  19         public void handleMessage(Message msg) {  20             if (msg.what == MyMessengerService.MSG_FROM_SERVER_TO_CLIENT) {  21                 Log.w(TAG, "reveive msg from server");  22  }  23  }  24  }  25 
 26     private class MyServiceConnection implements ServiceConnection {  27 
 28  @Override  29         public void onServiceConnected(ComponentName name, IBinder binder) {  30             Log.w(TAG, "in MyServiceConnection onServiceConnected");  31             mServerMessenger = new Messenger(binder);  32 
 33             mBound = true;  34  }  35 
 36  @Override  37         public void onServiceDisconnected(ComponentName name) {  38             // This is called when the connection with the service has been  39             // unexpectedly disconnected -- that is, its process crashed.
 40             Log.w(TAG, "in MyServiceConnection onServiceDisconnected");  41 
 42             mBound = false;  43  }  44  }  45 
 46  @Override  47     protected void onCreate(Bundle savedInstanceState) {  48         super.onCreate(savedInstanceState);  49  setContentView(R.layout.c);  50 
 51         bindServiceBtn = (Button) findViewById(R.id.bind_service);  52         unbindServiceBtn = (Button) findViewById(R.id.unbind_service);  53         sendMsgToServerBtn = (Button) findViewById(R.id.send_msg_to_server);  54 
 55         bindServiceBtn.setOnClickListener(new View.OnClickListener() {  56  @Override  57             public void onClick(View v) {  58                 Intent intent = new Intent(CActivity.this, MyMessengerService.class);  59  bindService(intent, sc, Context.BIND_AUTO_CREATE);  60  }  61  });  62 
 63         unbindServiceBtn.setOnClickListener(new View.OnClickListener() {  64  @Override  65             public void onClick(View v) {  66  excuteUnbindService();  67  }  68  });  69 
 70         sendMsgToServerBtn.setOnClickListener(new View.OnClickListener() {  71  @Override  72             public void onClick(View v) {  73  sayHello();  74  }  75  });  76 
 77         new Handler().postDelayed(new Runnable() {  78  @Override  79             public void run() {  80                 Intent intent = new Intent(CActivity.this, MyAlarmBroadcastReceiver.class);  81  sendBroadcast(intent);  82  }  83         }, 3 * 1000);  84 
 85  }  86 
 87     public void sayHello() {  88         if (!mBound)  89             return;  90         // Create and send a message to the service, using a supported 'what' value
 91         Message msg = Message.obtain(null, MyMessengerService.MSG_FROM_CLIENT_TO_SERVER, 0, 0);  92         // 经过replyTo把client端的Messenger(信使)传递给service
 93         msg.replyTo = mClientMessenger;  94         try {  95  mServerMessenger.send(msg);  96         } catch (RemoteException e) {  97  e.printStackTrace();  98  }  99  } 100 
101     private void excuteUnbindService() { 102         if (mBound) { 103  unbindService(sc); 104             mBound = false; 105  } 106  } 107 
108  @Override 109     protected void onDestroy() { 110         super.onDestroy(); 111         Log.w(TAG, "in onDestroy"); 112  excuteUnbindService(); 113  } 114 }

其中,须要注意的几点是:

1.MyMessengerService自定中,经过new Messenger(new ServerHandler())建立Messenger对象,在onBind(..)回调中,经过调用Messenger对象的getBinder()方法,将Binder返回;

2.Client在ServiceConnection的onServiceConnected(..)的回调中,经过new Messenger(binder)获取到Service传递过来的mServerMessenger;

3.接下来,就能够经过mServerMessenger.send(msg)方法向Service发送message,Service中的Messenger构造器中的Handler便可接收到此信息,在handleMessage(..)回调中处理;

4.至此只是完成了从Client发送消息到Service,一样的道理,想实现Service发送消息到Client,能够在客户端定义一个Handler,并获得相应的Messenger,在Clinet发送消息给Service时,经过msg.replyTo = mClientMessenger方式将Client信使传递给Service;

5.Service接收到Client信使后,获取此信使,并经过mClientMessenger.send(toClientMsg)方式将Service消息发送给Client。

至此,完成了Client - Service之间的双向通讯流程。

 

3).AIDL(Android Interface Definition Language)

通常状况下,Messenger这种方式都是能够知足需求的,固然,经过自定义AIDL方式相对更加灵活。

这种方式须要本身在项目中自定义xxx.aidl文件,而后系统会自动在gen目录下生成相应的接口类文件,接下来整个的流程与Messenger方式差异不大,网上也有很多实例,在此再也不具体给出。

 

注:不管哪一种方式的Bound Service,在进行unbind(..)操做时,都须要注意当前Service是否处于已经绑定状态,不然可能会由于当前Service已经解绑后继续执行unbind(..)会致使崩溃。这点与Started Service区别很大(如前文所述:stopService(..)无需作当前Service是否有效的判断)。

 

4.Local Service  VS Remote Service

Local Service:很多人又称之为”本地服务“,是指Client - Service同处于一个进程;

Remote Service:又称之为”远程服务“,通常是指Service处于单独的一个进程中。

其余使用上上文中基本上都有所述。

 

5.Service特性

1.Service自己都是运行在其所在进程的主线程(若是Service与Clinet同属于一个进程,则是运行于UI线程),但Service通常都是须要进行”长期“操做,因此常常写法是在自定义Service中处理”长期“操做时须要新建线程,以避免阻塞UI线程或致使ANR;

2.Service一旦建立,须要中止时都须要显示调用相应的方法(Started Service须要调用stopService(..)或Service自己调用stopSelf(..), Bound Service须要调用unbindService(..)),不然对于Started Service将处于一直运行状态,对于Bound Service,当Client生命周期结束时也将所以问题。也就是说,Service执行完毕后,必须人为的去中止它。

 

6.IntentService

IntentService是系统提供给咱们的一个已经继承自Service类的特殊类,IntentService特殊性是相对于Service自己的特性而言的:

1.默认直接实现了onBind(..)方法,直接返回null,并定义了抽象方法onHandlerIntent(..),用户自定义子类时,须要实现此方法;

2.onHandlerIntent(..)主要就是用来处于相应的”长期“任务的,而且已经自动在新的线程中,用户无语自定义新线程;

3.当”长期“任务执行完毕后(也就是onHandlerIntent(..)执行完毕后),此IntentService将自动结束,无需人为调用方法使其结束;

4.IntentService处于任务时,也是按照队列的方式一个个去处理,而非真正意义上的多线程并发方式。

下面是一个基本的继承自IntentService的自定义Service:

 1 public class MyIntentService extends IntentService {  2 
 3     public static final String TAG = "MyIntentService";  4 
 5     public MyIntentService() {  6         super(TAG);  7  }  8 
 9     public MyIntentService(String name) { 10         super(name); 11  } 12 
13  @Override 14     protected void onHandleIntent(Intent intent) { 15         Log.w(TAG, "in onHandleIntent"); 16         Log.w(TAG, "thread name:" + Thread.currentThread().getName()); 17  } 18 
19 }

 

7.前台Service

Android中Service接口中还提供了一个称之为”前台Service“的概念。经过Service.startForeground (int id, Notification notification)方法能够将此Service设置为前台Service。在UI显示上,notification将是一个处于onGoing状态的通知,使得前台Service拥有更高的进程优先级,而且Service能够直接notification通讯。

下面是一个简单的前台Service使用实例:

 1 public class MyService extends Service {  2 
 3     public static final String TAG = "MyService";  4 
 5  @Override  6     public IBinder onBind(Intent intent) {  7         return null;  8  }  9 
10  @Override 11     public void onCreate() { 12         super.onCreate(); 13         Log.w(TAG, "in onCreate"); 14  } 15 
16  @Override 17     public int onStartCommand(Intent intent, int flags, int startId) { 18         Log.w(TAG, "in onStartCommand"); 19         Log.w(TAG, "MyService:" + this); 20         String name = intent.getStringExtra("name"); 21         Log.w(TAG, "name:" + name); 22 
23         
24         Notification notification = new Notification(R.drawable.ic_launcher, "test", System.currentTimeMillis()); 25         Intent notificationIntent = new Intent(this, DActivity.class); 26         PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntesnt, 0); 27         notification.setLatestEventInfo(this, "title", "content", pendingIntent); 28         startForeground(1, notification); 29         
30 
31         return START_REDELIVER_INTENT; 32  } 33 
34  @Override 35     public void onDestroy() { 36         super.onDestroy(); 37         Log.w(TAG, "in onDestroy"); 38  } 39 }
相关文章
相关标签/搜索