Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

第 127 章 Service 服务

目录

127.1. Service的基本用法
127.1.1. manifest 文件
127.1.2. 创建 Service
127.1.3. Layout 代码
127.1.4. Activity 代码
127.2. Service 中启动线程
127.3. Service 和 Activity 通信
127.3.1. Layout
127.3.2. Service
127.3.3. Activity
127.4. Service 和 Toast
127.5. Service 中启动 Activity
127.6. Service 中更新 UI
127.7. 前台启动 Service

手动调用方法

			
手动调用方法		作用
startService()	启动服务
stopService()	关闭服务
bindService()	绑定服务
unbindService()	解绑服务

			
	

自动调用的方法

			
自动调用方法			作用
onCreate()			创建服务
onStartCommand()	开始服务
onDestroy()			销毁服务
onBind()			绑定服务
onUnbind()			解绑服务
			
	

生命周期调用

			

1. 启动Service服务

单次:startService() —> onCreate() —> onStartCommand()
多次:startService() —> onCreate() —> onStartCommand() —> onStartCommand()

2. 停止Service服务

stopService() —> onDestroy()

3. 绑定Service服务

bindService() —> onCreate() —> onBind()

4. 解绑Service服务

unbindService() —> onUnbind() —> onDestroy()

5. 启动绑定Service服务

startService() —> onCreate() —> onStartCommand() —> bindService() —> onBind()

6. 解绑停止Service服务

unbindService() —> onUnbind() —> stopService() —> onDestroy()

7. 解绑绑定Service服务

unbindService() —> onUnbind(ture) —> bindService() —> onRebind()

			
	

127.1. Service的基本用法

127.1.1. manifest 文件

			
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.netkiller.service">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"></service>
    </application>

</manifest>			
			
			

这段代码不是手工加入的,只需在 Android Studio 中选择 File - New - Service - Service 创建 Service 会自动加入下面代码

			
<service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"></service>			
			
			

127.1.2. 创建 Service

在 Android Studio 中选择 File - New - Service - Service 创建 Service

MyService继承自Service,并重写父类的onCreate()、onStartCommand()和onDestroy()方法

			
package cn.netkiller.service;

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

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

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("Service", "onCreate() executed");
        Log.d("Service", "MyService thread id is " + Thread.currentThread().getId());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("Service", "onStartCommand() executed");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("Service", "onDestroy() executed");
    }

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

			
			

onCreate() Service 创建的时候执行,已经创建的Service不会再执行

onStartCommand() 任何时候,只要执行 startService(intent); 便会执行

onDestroy() 停止的时候执行

127.1.3. Layout 代码

在布局文件中加入了两个按钮,一个用于启动Service,一个用于停止Service

			
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="368dp"
        android:layout_height="229dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0">

        <Button
            android:id="@+id/startService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Start service" />

        <Button
            android:id="@+id/stopService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Stop service" />
    </LinearLayout>

</android.support.constraint.ConstraintLayout>			
			
			

127.1.4. Activity 代码

			
package cn.netkiller.service;

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

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button startService;
    private Button stopService;

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

        startService = (Button) findViewById(R.id.startService);
        stopService = (Button) findViewById(R.id.stopService);
        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);

        Log.d("Service", "MainActivity thread id is " + Thread.currentThread().getId());

    }

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