Service并不是在单独进程中运行,也是运行在应用程序进程的主线程中,在执行具体耗时任务过程中要手动开启子线程,应用程序进程被杀死,所有依赖该进程的服务也会停止运行。
由于ANR对Activity和BroadcastReceiver响应时间的限制(Activity对事件响应不超过5秒,BroadcastReceiver执行不超过10秒),使得在其中都不适合执行较耗时操作,这样像网络、数据库、复杂计算这类耗时操作的执行就需要一个组件来承担。Service作为Android四大组件之一,其功能之一就是耗时操作的执行,主要功能如下:
Service的使用
Service的创建和Activity类似,也是通过Intent来实现的,既然是安卓四大组件之一,那么它也需要在清单文件中进行注册的。具体步骤如下。
Service的创建
新建一个TgsService继承自Service,并重写父类的onCreate()、onStartCommand()和onDestroy()方法,如下面的代码所示:
public class TgsService extends Service {
public static final String TAG = "TgsService";
@Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate"); }
@Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand"); return super.onStartCommand(intent, flags, startId); }
@Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy"); }
@Override public IBinder onBind(Intent intent) { return null; }}
Service的注册
在清单文件中注册它,如下所示:
<service android:name="com.tgs.demo.TgsService" android:enabled="true" android:exported="true"/>
Service的启动
接下来创建一个TgsActivity的测试活动,用于在其中创建TgsService对象,并在点击按钮时启动服务,示例代码如下:
public class TgsActivity extends Activity implements View.OnClickListener {
private Button startBtn;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_start);
startBtn = (Button) findViewById(R.id.btn_start_service);
startBtn.setOnClickListener(this); }
@Override public void onClick(View v) { if (v != null) { switch (v.getId()) { case R.id.btn_start_service: Intent startIntent = new Intent(this, TgsService.class); startService(startIntent); break; } } }}
Service和Thread
如第一节所介绍的,Service是一个运行于后台的服务,一些比较耗时的操作也可以放在这里运行。而Thread我们大家都知道,是用于开启一个子线程,在这里去执行一些耗时操作就不会阻塞主线程的运行。这就会让人对这两个概念产生混淆了。
Service和Thread到底有什么关系呢?什么时候应该用Service,什么时候又应该用Thread?答案是:Service和Thread之间没有任何关系!前面有提到,Service其实是运行在主线程里的,因此它和Thread并没有关系。
Service与Thread的区别如下:
那么如果用户既想使用Service的优点,又想使用Thread的优点,要怎么实现?关于这一点,Google已经帮我们想到了。即下节要介绍的IntentService。
IntentService
IntentService的概念
IntentService是Android中的一个系统封装类,继承自四大组件之一的Service,主要用于处理异步请求,实现多线程,它有以下特点:
IntentService的创建
编写自己的Service类继承IntentService,并重写其中的onHandleIntent(Intent)方法,该方法是IntentService的一个抽象方法,用来处理我们通过startService方法开启的服务,传入参数Intent就是开启服务的Intent,如下所示:
public class TgsIntentService extends IntentService {
private static final String TAG = TgsIntentService.class.getSimpleName();
public TgsService() { super(TAG); }
@Override protected void onHandleIntent(Intent intent) { // 在这里添加我们要执行的异步代码 }}
IntentService的注册
接下来在AndroidManifest文件中的Application标签下添加刚刚创建的服务,如下所示:
<service android:name="com.tgs.demo.TgsIntentService" />
IntentService的启动
然后创建一个TgsActivity的测试活动,并在点击按钮时调用startService系统函数来开启IntentService的服务,示例代码如下:
public class TgsActivity extends Activity implements View.OnClickListener {
private Button startIntentServiceBtn;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_start);
startIntentServiceBtn = (Button) findViewById(R.id.btn_start_intent_service);
startIntentServiceBtn.setOnClickListener(this); }
@Override public void onClick(View v) { if (v != null) { switch (v.getId()) { case R.id.btn_start_intent_service: Intent intent = new Intent(TgsActivity.this, TgsIntentService.class); startService(intent); break; } } }}
Service的终止
一个已经启动了的Service必须管理它自己的生命期,系统不会停止或销毁这种Service,除非内存不够用了。Service在onStartCommand()返回后会继续运行。所以,service必须调用stopSelf()停止自己或由另一个组件调用stopService()来停止它。
一旦通过stopSelf()或stopService()发出了停止请求,系统就会尽可能快地销毁service。
关于Service的终止,需要注意以下几点:
接下来创建一个TgsActivity的测试活动,用于在其中创建TgsService对象,并在点击按钮时停止服务,示例代码如下:
public class TgsActivity extends Activity implements View.OnClickListener {
private Button stopBtn;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_start);
stopBtn = (Button) findViewById(R.id.btn_stop_service);
stopBtn.setOnClickListener(this); }
@Override public void onClick(View v) { if (v != null) { switch (v.getId()) { case R.id.btn_stop_service: Intent stopIntent = new Intent(this, TgsService.class); stopService(stopIntent); break; } } }}
参考链接
客户端27
Android开发12
客户端 · 目录
上一篇Android多线程的种类及使用方法下一篇Android组件之ContentProvider