Android 服务学习(二)——服务的基本用法

新建一个day17_ServiceTest空项目

一、定义一个服务

在这里插入图片描述
默认代码:

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");
    }
}

这个服务类是继承于Service类的,其中必须实现抽象方法onBind()
服务中最常见的三个重写方法:

  • onCreate():创建时调用
  • onStartCommand():启动时调用
  • onDestroy():销毁时调用

服务也需要注册:

<service
     android:name=".MyService"
     android:enabled="true"
     android:exported="true">
</service>
  • Exported表示是否允许其他程序访问此服务
  • Enabled表示是否启用此服务

二、启动和停止服务

主布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

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

</LinearLayout>

主活动:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

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

        Button button_start = findViewById(R.id.start);
        Button button_stop = findViewById(R.id.stop);
        button_start.setOnClickListener(this);
        button_stop.setOnClickListener(this);
    }

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

首先new一个Intent出来,第二个参数是Service实例,调用startService()stopService()即可运行或停止服务

怎么样服务主动停止呢,只需要在服务类里调用stopSelf()即可

修改服务:

public class MyService extends Service {
    private static final String TAG = "MyService";
    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();
        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: 销毁服务");
    }
}

运行:
在这里插入图片描述

三、服务和活动通信

通信需要在服务中借助onBind()方法,一般需要创建一个专门的Binder对象管理。

模拟下载功能:

1、服务类

public class MyService extends Service {
    private static final String TAG = "MyService";
    private DownloadBinder mBinder = new DownloadBinder();
    
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
......
    class DownloadBinder extends Binder {
        public void startDownload(){
            Log.d(TAG, "startDownload: 开始下载");
        }
        
        public int getProgress(){
            Log.d(TAG, "getProgress: 获取进度");
            return 0;
        }
    }
}

2、主布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

......
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/bind_service"
        android:text="绑定服务"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/unbind_service"
        android:text="解绑服务"/>
        

</LinearLayout>

3、主活动

当活动和服务绑定以后,就可以调用服务里的Binder提供的方法了

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private MyService.DownloadBinder downloadBinder;
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            downloadBinder = (MyService.DownloadBinder) service;
            downloadBinder.startDownload();
            downloadBinder.getProgress();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

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

        Button button_start = findViewById(R.id.start);
        Button button_stop = findViewById(R.id.stop);
        button_start.setOnClickListener(this);
        button_stop.setOnClickListener(this);
        
        Button button_bind = findViewById(R.id.bind_service);
        Button button_unbind = findViewById(R.id.unbind_service);
        button_bind.setOnClickListener(this);
        button_unbind.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start:
                Intent intent_start = new Intent(this, MyService.class);
                startService(intent_start);
                break;
            case R.id.stop:
                Intent intent_stop = new Intent(this, MyService.class);
                stopService(intent_stop);
                break;
            case R.id.bind_service:
                Intent intent_bind = new Intent(this, MyService.class);
                bindService(intent_bind, connection, BIND_AUTO_CREATE); // 绑定服务
                break;
            case R.id.unbind_service:
                unbindService(connection);  // 解绑服务
                break;
            default:
                break;
        }
    }
}
  1. 创建了ServiceConnected匿名类,重写了里面的onServiceConnected()onServiceDisconnected()方法,这两个方法会在绑定成功和连接断开时调用
  2. onServiceConnected()Service向下转型为自定义的DownloadBinder实例,然后用这个实例就能调用在DownloadBinder中的任何方法【必须先绑定】
  3. bindService()可以将活动和服务绑定,第一个参数是Intent对象【和服务联系起来】,第二个参数是创建好的ServiceConnection实例【指定要绑定的服务】,第三个参数是一个标志位,传入BIND_AUTO_CREATE表示绑定后自动创建服务【onCreate()执行,onStartCommand()不执行【即创建而不启动】】
  4. 解绑unBindService(),参数就是绑定好的ServiceConnection实例
  5. 一个服务可以与不同的活动绑定,绑定后会获取到相同的实例

4、运行

在这里插入图片描述

四、服务的生命周期

  1. 调用Context.startService()服务就会启动并回调onStartCommand()方法,若服务还未创建过,就会先执行onCreate()
  2. 服务启动后一直处于运行状态,直到Context.stopService()stopSelf()被调用
  3. 每个服务都只会存在一个实例,不管调用多少次startService(),都只会存在一个实例,关闭只需一次
  4. 通过Context.bindService()获取服务的持久连接,就会回调服务的onBind()方法,onBind()返回一个IBinder对象实例,就能实现自由通信了
  5. 调用Context.stopService()服务就会被销毁并回调onDestroy()方法
  6. 类似的,被绑定的服务执行unbindService()也会被销毁,而且回调onDestroy()
  7. 如果一个服务既执行了startService(),也执行了bindService(),那么,销毁这个服务就必须都执行stopService()unbindService()才能被销毁,onDestroy()才能被执行
发布了166 篇原创文章 · 获赞 14 · 访问量 9098

猜你喜欢

转载自blog.csdn.net/qq_41205771/article/details/104363163