您的位置:首页 > 其它

后台服务(Service)简述

2015-06-18 17:43 357 查看
一、简介

Service是应用的后台服务,它用来执行不需与用户交互的、耗时的操作,或者给其他应用提供一些功能。Service默认运行在用户界面(Activity)所在的主线程中,所以它的执行速度越快越好。如果有耗时较长或者会阻塞的操作,可以在Service中创建一个线程去完成它。若Service的执行时间超过5秒,系统会抛出“应用程序无响应(ANR)”的对话框。

二、注册Service

所有Service都应该在所在应用的AndroidManifest.xml中注册相应的标签,否则将无法被Activity连接(包括start和bind)。

<manifest ... >

...

<application ... >

<service
<!-- 设置本服务的类名 -->
android:name=".TestService"
<!-- 设置本服务作为一个单独的进程。省略这行代码的话,它将运行于主线程中 -->
android:process=":任意名称"
<!-- 是否接收其他应用的启动请求 -->
android:exported="false"
/>

...

</application>

</manifest>


三、连接Service

Service可以同时被多个Activity经调用startService()或bindService()来连接,每次它都会以onStartCommand()或onBind()来响应,但其onCreate()只会在Service对象首次创建时调用。如果不想提供绑定,可以让onBind()返回null。

四、断开Service

绑定上的Activity可以调用unbindService()来解除绑定。当所有Activity都解绑后,系统就会调用服务的onUnbind()方法(若无其他Activity启动服务,则服务会被销毁)。启动服务的Activity可以调用stopService()来停止服务,服务也可以自己调用stopSelf()来停止,但这两种方法的前提是服务未被绑定。停止时,系统会调用onDestory()来销毁服务。



五、生命周期

Service的生命周期从onCreate()开始,到onDestroy()或者被系统杀死时结束。在空闲内存不足时,系统会杀掉一些进程,Service已启动的时间越长,越容易被系统杀死。在Service被可见进程所绑定期间,它所在的进程也将被认为是可见进程(除非绑定时另行指定),使得它的进程不那么容易被杀死。当Service正在运行onCreate()、onStartCommand()、onDestory()时,或者调用了startForeground(),系统会把它所在的进程当做前台进程,这样只有在极端低内存的情况下它的进程才会被杀死。

六、线程安全

Android提供了一个线程安全的、继承自Service的IntentService类,继承它之后只需实现其onHandleIntent方法则可,该方法负责具体的工作任务。IntentService仅支持startService(),而不支持bindService()。每当有Activity连接上来时,它都会创建一个工作线程加入到由它管理的工作队列中。工作线程们依次调用onHandleIntent(),执行完毕后才轮到下一个。当所有的工作线程都干完活时,IntentService对象会自动销毁,以节省资源。

public class TestIntentService extends IntentService
{
public IntentService()
{
super("随便起个名字");
}

protected void onHandleIntent(Intent intent)
{
/**
* 工作线程们依次进来干活,执行完毕后才轮到下一个。
* 任务相关信息会经由startService(intent)的参数传进来。
*/
}
}


七、样例代码

package com.example.wesnoth;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;

public class TestActivity extends Activity
{
private Intent intent = new Intent(TestActivity.this, TestService.class);
private TestService.MyBinder myBinder = null;
private TestServiceConnection testServiceConnection = new TestServiceConnection();

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.XXXXXXX);
// 注意:应当使用指定了目标Service类名的
// 显式Intent来启动Service。
// 否则Android 5.0(API 21)以上系统会抛出异常
Intent intent = new Intent(this, DownloadService.class);
if (true)
{
/**
* 启动服务。
*/
startService(intent);
}
else
{
/**
* 绑定服务。
*/
bindService(intent, testServiceConnection, BIND_AUTO_CREATE);
}
}

@Override
protected void onDestroy()
{
super.onDestroy();
if(true)
{
/**
* 停止服务。
* 此时不管是否有其他Activity连接,都会进入到Service.onDestroy()
*/
stopService(intent);
}
else
{
/**
* 解绑服务
*/
unbindService(intent);
}
}

class TestServiceConnection implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
/**
* 当绑定Service成功时,进入此方法
*/
myBinder = (TestService.MyBinder)service;
}

@Override
public void onServiceDisconnected(ComponentName name)
{
/**
* 当Service所在的进程崩溃掉或者被杀掉时,进入此方法。
* 此时并不会断开与Service的连接,等到Service所在的进程重启时,
* 会重新调用onServiceConnected()
*/
myBinder = null;
}
}

}


package com.example.wesnoth;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class TestService extends Service
{
private MyBinder myBinder = new MyBinder();

@Override
public void onCreate()
{
/**
* 本方法只会在Service对象首次创建时调用。
*/
super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
// 可以在这里创建处理任务的线程。
// 线程完成任务后可以调用stopSelf(startId);
// 如果最后一个启动服务的ID与startId匹配,
// 就会销毁服务,否则不销毁。

/**
* 当有Context对象调用startService()时,调用此方法。
*/
return super.onStartCommand(intent, flags, startId);
}

@Override
public IBinder onBind(Intent intent)
{
/**
* 当首次被Activity绑定时,调用此方法。
* 系统会保存IBinder,
* 后续的绑定将不调用此方法而是直接返回它。
* 如果不想提供绑定,可以返回null
*/
return myBinder;
}

@Override
public boolean onUnbind(Intent intent)
{
/**
* 当所有已绑定的Activity都调用了unbindService()来解绑,
* 就会调用onUnbind()。
*/
return super.onUnbind(intent);
}

@Override
public void onDestroy()
{
/**
* 当所有已绑定的Activity都调用了unbindService()来解绑,
* 此时若没有任何Activity已通过startService来连接的话,才会调用onDestory()。
* 若某个Activity调用了stopService,或者Service自己调用了stopSelf(),
* 此时不管还有没有其他连接,都会调用onDestroy()。
*/
super.onDestroy();
}

// 注意:这个Binder的所有公开方法都需要做到线程安全
public class MyBinder extends Binder
{
// 这个方法可以给bind上的Activity调用
public void doSomething()
{
// 处理任务
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息