什么是服务?
服务是Android四大组件之一,与Activity一样,代表可执行程序。Service不像Activity有可以操作的用户界面,它主要用于在后台处理一些耗时的操作。或者执行某些长期运行的任务。必要时我们甚至可以在程序退出的情况下,让Service在后台继续保持运行的状态。
服务分为:本地服务(启动服务)和远程服务(绑定服务)。
一、Service(启动服务)的基本用法:
关于Service最基本的用法就是如何启动一个Service,启动Service的方法与启动Activity很相似,都需要Intent来实现,下面我就通过一个具体的列子来认识。
1、首先我们在布局文件中加入两个Button按钮,一个是启动服务,一个是停止服务。代码如下:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="START"
android:onClick="ServiceStart"
android:layout_gravity="center"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="STOP"
android:onClick="ServiceStop"
android:layout_gravity="center"
/>
2、然后在MainActivity.java作为程序的主Activity,在此写启动服务和停止服务的逻辑。在启动服务(ServiceStart)的按钮点事件中,我们构建一个Intent对象,并调用startService()方法来启动ServiceState;在停止服务(ServiceStop)的按钮点击事件中,也是构建Intent对象,并调用stopService()方法来停止 ServiceState。代码如下:
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent();
}
public void ServiceStart(View view){
intent.putExtra("data","下载的路径:");
startService(intent);
}
public void ServiceStop(View view){
//停止服务有二种:(1)stopService (2)stopself
stopService(intent);
}
//创建服务
@Override
public void onCreate() {
super.onCreate();
Log.i("test", " onCreate");
}
//开启服务
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String data=intent.getStringExtra("data");
Log.i("test", "onStartCommand:"+data);
//ANR:应用程序未效应:因为耗时操作写到了主线程,解决只需要将耗时操作写到子线程
//服务与线程的区别:
new MyThread(startId).start();
return super.onStartCommand(intent, flags, startId);
}
//销毁服务
@Override
public void onDestroy() {
Log.i("test", "onDestroy");
super.onDestroy();
}
class MyThread extends Thread{
private int starId;
//写一个构造方法
public MyThread(int startId) {
this.starId= startId;
}
@Override
public void run() {
super.run();
//耗时操作
for (int i = 0; i <10; i++) {
Log.i("test", "i="+i);
SystemClock.sleep(1000);
}
//停止服务
//stopSelf();(1)无参:当第一个线程执行完毕,则会停止服务
//(2)有参:所有的线程都执行完毕,才停止服务
stopSelf(starId);
}
}
4、注意:每一个Service都必须在清单文件(AndroidManifest.xml)中注册。代码如下:
<!--注册服务:android:exported="true":可以被其他组件启动-->
<service android:name=".ServiceState"
android:exported="true">
</service>
5、总结:
(1)、当启动一个Service的时候,会调用Service中的onCreate()和onStartCommand()方法。
(2)、服务与线程的区别:
<1>服务不是单一的进程。服务没有自己的进程,应用程序可以不同,服务运行在相同的进程中。
<2>服务不是线程,线程可以在服务中工作。
在应用中,如果是长时间在后台运行。而且不需要交互的情况下,使用服务;同样是在后台运行,不需要交互的情况下,如果只是完成某个任务,之后就不需要运行,而且可能是多个任务,需要长时间运行的情况下使用线程。
如果任务占用CPU时间多,资源大的情况下,要使用线程。
<3>线程是程序执行的最小单元,它是分配CPU的基本单位;可以用Thread来执行异步的操作。
<4>服务是Android的一种机制。
public ServiceIntent( ) {
super("");
}
public ServiceIntent(String name) {
super(name);
}
@Override
protected void onHandleIntent(Intent intent) {
//1、可以之间进行耗时操作 2、有序的执行操作
for (int i = 0; i <10 ; i++) {
Log.i("test","i="+i);
SystemClock.sleep(200);
}
}
在清单文件中注册代码如下:
<service android:name=".ServiceIntent"
android:exported="true">
</service>
总结:
<1>Service本身存在两个问题:
1、Service不会专门启动一条单独的进程,Service与它所在应用位于同一个进程中;
2、Service也不是专门一条新线程,因此不应该在Service中直接处理耗时的操作。
<2>启动ServiceIntent.java会使用它内部的线程,因此不会阻塞前台的UI线程,而ServiceState.java会。