首先,Service适合做的事:后台稳定运行不需要界面或不想让人看见的。

Service有两种启动方式:

一. startService :
1.首先,新建一个类,让它继承Service,重写

onCreate( )
onStartCommand(Intent intent, int flags, int startId)
onDestroy( )

这三个方法。别说话,看代码

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

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

其中,onBind方法是抽象方法,必须实现,这里我们暂时用不上它,onStartCommand方法现在站的位置本来是onStart的,后来onStart被抛弃(过期)了。Service框架已经搭好了,

别忘了在清单文件里注册

<service
            android:name="com.hyw.servicedemo.MyService"
            android:enabled="false"
            android:exported="false" >
        </service>

接下来我们启动它。我们在布局里添加一个button,点击之后让它执行:

Intent intent = new Intent(this,MyService.class);
startService(intent);

其中this是当前这个Activity,MyService.class就是刚才创建的服务。通过startService方法启动它。

布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.hyw.servicedemo.MainActivity">

    <Button
        android:id="@+id/start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="启动服务" />
</RelativeLayout>

代码:

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button start;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        start = (Button) findViewById(R.id.start);
        start.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.start:
                Intent intent = new Intent(this,MyService.class);
                startService(intent);
                break;
            default:
                break;
        }
    }
}

非常不巧编译器打印不出log,然后我用Toast来测试

当我们点击开启服务之后

android startservice 任务打断 安卓startservice_Service

会弹出onCreate和onStartCommand方法里的Toast(通过startService开启服务是不会调用onBind方法的),再点开启服务,只弹出onStartCommand方法里的Toast,然后无论按home还是按返回键退出应用,进到手机设置里的应用选项,会发现正在运行里有我们的应用(一个进程和一个服务),接下来我们怎么关闭这个Service呢?

android startservice 任务打断 安卓startservice_服务_02

当点击关闭服务的时候,我让他执行

Intent intent2 = new Intent(this,MyService.class);
stopService(intent2);

注意我又new了一个Intent哦,这时候弹出onDestroy里的Toast。这时候再进应用里看,正在运行的应用没有我们这个应用了。

还有一种方法可以停止服务,就是在Service里调用

stopSelf();

方法。

如果我代码这样写的话

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "onStartCommand", Toast.LENGTH_SHORT).show();
        stopSelf();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Toast.makeText(this, "onDestroy", Toast.LENGTH_SHORT).show();
        super.onDestroy();
    }

点击开启服务,弹出onStartCommand之后又会弹出onDestroy,而且在应用正在运行里也不会有我们的应用。它可以自己结束自己。

所以通过StartService启动的服务的生命周期是这样的:开启服务的时候会相继调用onCreate和onStartCommand方法,这就算是开启了,你再执行开启命令,只会调用onStartCommand方法了,所以初始化什么的要写在onCreate里比较好。service就像是一个单例模式的类,在手机里一个服务只会有一个,正确来说服务就是服务器,其他启动它的组件就是客户端,这也是google这样设计的,服务器之后一个,然后很多客户端可以跟它打招呼,服务会响应客户端的请求,但服务一般不会主动要求客户端干什么,所以service与activity的通信google设计的是只能activity操控service,而不能反过来,具体后面讲

当服务开启的时候,就算启动它的组件销毁了,服务还是存在,

停止服务的时候,无论是不是启动它的那个Intent,无论那个组件,都可以结束它,只要你有这个想法(intent里是不是这个Service)和这个能力(stopService方法)。所以服务也可以开启服务。

有一个问题?Service是在子线程执行的吗?

答案当然是否定的。

不然我怎么可以弹出Toast。
如果有要在子线程执行的耗时操作,可以在Service里新建一个线程执行,或者让这个类继承IntentService而不是Service,需要说明的是就算服务结束了,子线程如果还有事没做完,子线程还是会在后台继续执行的。