Service
一。Serivce的启动方式分两种
1.startService。用这种方式启动的话,负责启动这个service的Activity或者其他组件即使被销毁了,Service也会继续在后台运行,必须得Serivce自己做完任务区去调用stopSelf或者stopService去停止这个Serice。这种方式是Start方式
2.bindService。这种方式要组件去调用BindService去绑定一个Service,这种方式Service的生命周期是知道所有绑定这个service的组件unbind之后才会销毁。这种方式称之为 Bound
startService调用后会自动调用startCommand,你需要做的工作可以在这里写,例如启动新线程去执行任务之类的。
bindService之后会调用Onbind函数,功能同上,需要自己去重写,还有就是通信就是通过这个onbind函数返回的IBinder。
以上两种方式可以一起使用,不是一定要分开。。
二.实现Service需要重写的方法
一般来说,实现Service,实现以下几个方法就好:
函数名字还是非常清楚的,具体作用就不说了。
三.在manifest里面加入Service
跟Activity一样,要使用你自己写的Service,必须得在manifest里面注册
例如
<manifest ... > ... <application ... > <service android:name=".ExampleService" /> ... </application> </manifest>
Service的名字一旦确定,就不要更改了,因为其他地方会利用这个名字去访问Service,
值得注意的是,一个service可以被其他应用程序去访问,如果你不想被其他应用程序访问,就在文件里面加入属性android:exported,然后设置为False。
四.实现Service的两种方法
实现Service主要有两种方式:
1.Service
要重写几个函数,而且一般工程来说,都要自己创建新线程来执行任务,这些工作都要我们自己去编写来做。
代码如下:
public class HelloService extends Service { private Looper mServiceLooper; private ServiceHandler mServiceHandler; // Handler that receives messages from the thread private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { // Normally we would do some work here, like download a file. // For our sample, we just sleep for 5 seconds. long endTime = System.currentTimeMillis() + 5*1000; while (System.currentTimeMillis() < endTime) { synchronized (this) { try { wait(endTime - System.currentTimeMillis()); } catch (Exception e) { } } } // Stop the service using the startId, so that we don't stop // the service in the middle of handling another job stopSelf(msg.arg1); } } @Override public void onCreate() { // Start up the thread running the service. Note that we create a // separate thread because the service normally runs in the process's // main thread, which we don't want to block. We also make it // background priority so CPU-intensive work will not disrupt our UI. HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); // Get the HandlerThread's Looper and use it for our Handler mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); // For each start request, send a message to start a job and deliver the // start ID so we know which request we're stopping when we finish the job Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; mServiceHandler.sendMessage(msg); // If we get killed, after returning from here, restart return START_STICKY; } @Override public IBinder onBind(Intent intent) { // We don't provide binding, so return null return null; } @Override public void onDestroy() { Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); } }
2.IntentService
如果只是启动一个线程做一个单独任务,这个是首选,系统帮你实现好了几个必须重写的函数,你只需要做的是事情就是实现一个函数就行:onHandleIntent(intent) 参数是startCommand那里传过来的。
看代码:
public class HelloIntentService extends IntentService { /** * A constructor is required, and must call the super IntentService(String) * constructor with a name for the worker thread. */ public HelloIntentService() { super("HelloIntentService"); } /** * The IntentService calls this method from the default worker thread with * the intent that started the service. When this method returns, IntentService * stops the service, as appropriate. */ @Override protected void onHandleIntent(Intent intent) { // Normally we would do some work here, like download a file. // For our sample, we just sleep for 5 seconds. long endTime = System.currentTimeMillis() + 5*1000; while (System.currentTimeMillis() < endTime) { synchronized (this) { try { wait(endTime - System.currentTimeMillis()); } catch (Exception e) { } } } } }
注意,startCommand返回的值是有用的,决定这个service被系统干掉后要不要重新启动,这个值有三个枚举START_NOT_STICKY,START_STICKY,START_REDELIVER_INTENT
五.通过intent来开启Service
启动Service就是创建一个intent对象,参数传进去需要启动的Service名称,就可以啦,调用startService啦,
如果需要Service传回来一些消息,可以 用PendingIntent,然后传给startService用的intent,然后可以用getBroadcast来得到消息。
六.startForeground()来让service在前端显示
类似播放器一样,你想通知栏里面看到在放什么歌曲,还有点击放下一首时,需要调用startForeground()让service运行在前端
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), System.currentTimeMillis()); Intent notificationIntent = new Intent(this, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, getText(R.string.notification_title), getText(R.string.notification_message), pendingIntent); startForeground(ONGOING_NOTIFICATION_ID, notification);
具体Service的其他方面可以去看下官方文档