Service的两种用法

本文详细介绍了Android中的Service组件,包括startService和bindService的使用方法、特点与优缺点。通过示例代码展示了如何创建并启动这两种Service,强调了IntentService的队列执行特性以及与普通Service的区别。对于需要后台长时间运行的任务,如下载、上传,Service是理想的解决方案,但需要注意主线程的处理和资源管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是service,为什么要使用service

1.Service是 Android四大组件之一,和Acvtivity的级别相当
2.Service是可以长时间运行在后台的,是不可见的,是没有界面的
3.Service是运行在主线程的
4.Service可以跨进程调用

在真实的商业项自中都有定期在后台执行任务(如:下载、上传等)的需求。当某个功能需要执行很长时间(如:下载、收集数据等),并且在这个执行过程中不需要让用户操作,不需要Activity进行交互的情况下,可以通过Service在后台完成指定任务。

使用startService启动service

1.新建类继承service
2.重写onCreate方法
3.实现onBind抽象方法
4.重写onStartCommand方法

startService代码展示

xml的代码

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


    <Button
        android:id="@+id/start_btn"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="启动service"
        android:textSize="30sp" />


    <Button
        android:id="@+id/stop_btn"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="停止service"
        android:textSize="30sp" />
</LinearLayout>
        接下来在activity里面添加点击事件,使用switch语句。然后分别用startService和stopService来启动停止service。
package myapplication.com.example.sq;

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

public class MyActivity extends AppCompatActivity implements View.OnClickListener {

    private Button startBtn;
    private Button stopBtn;
    private Intent intent;

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

        bindID();
    }

    private void bindID() {
        startBtn = findViewById(R.id.start_btn);
        stopBtn = findViewById(R.id.stop_btn);


        stopBtn.setOnClickListener(this);
        startBtn.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.start_btn:

                intent = new Intent(MyActivity.this, MyService.class);
                startService(intent);
                break;
            case R.id.stop_btn:
                stopService(intent);
                break;
        }
    }
}

我们要想沉睡一秒,可以在onStartCommand方法里面写一个thread的子线程。可以打印一下。

     new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {

                    try {
                        Thread.sleep(1000);
                        Log.e("SERVICE" + Thread.currentThread().getName(), i + " ***");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

startService的特点和缺点

1.onCreate只会执行一次,只要调用startservice,onStartCommand一定会执行
2.Service运行的线程在主线程中,做耗时操作需要另开子线程
3.通过intent传参,在onStartCommand中接收参数
4.无法获得service对象,直接操作service中的属性和方法
5.调用stopservice,serv会执行service方法后停止。

优点:
使用简单,和activity一样,只要几行代码就行。

缺点:
使用startService方式。无法获得serv对象,不能直接操作service的属性和方法,只能通过intent传递不同的参数,重复调用startService,会触发onStartCommand

使用bindService方式的缺点、优点、特点

优点:可以得到service对象,灵活控制service内部的属性和方法
缺点:使用复杂
特点:
1.oncreate,onBind只执行一次
2.Service运行的线程在主线程中,做耗时操作需要另开子线程
3.可以直接操作service内部的属性和方法
4.调用unbindservice后,service会执行onunbind,ondestory方法会停止

bindservice的使用示例

先创建一个MyService1继承Service,然后再重写其他的方法,这边需要注意的是我们定义一个Guanjia 类来继承Binder,以此来得到service的对象

public class MyService1 extends Service {

    private String TAG="MySERVICE1";

    private  Guanjia guanjia=new  Guanjia();


    public  class  Guanjia extends Binder{
        //作用:得到当前Service的对象
        public  MyService1 getServiceObject(){
            return MyService1.this;
        }
    }

public  void fly(){
    Log.e("TAG","开飞机");
}


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e("TAG","onBind...");
        return guanjia ;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("TAG","onUnbind...");
        return super.onUnbind(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("TAG","onCreate..");
    }

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

    @Override
    public void onRebind(Intent intent) {
        super.onRebind(intent);
        Log.e("TAG","onRebind..");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("TAG","onDestroy...");
    }
}

然后在创建一个activity,创建三个button控件,分别赋上点击事件。在onclick里面写上switch语句。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="myapplication.com.example.sq.ZhangsanActivity"
    android:orientation="vertical">



    <Button
         android:id="@+id/bindBtn"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="绑定bind"
        android:textSize="20sp"
        />

    <Button

        android:id="@+id/jiechuBtn"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="解除bind"
        android:textSize="20sp"
        />

    <Button
        android:id="@+id/tiao_lisi"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="前往李四页面"
        android:textSize="20sp"/>
</LinearLayout>

在这里我们需要写一个ServiceConnection 来拿到拿到myService1对象,打印一下日志,我们可以看到他的执行方法的顺序。记住要manifest里面注册service标签。


public class ZhangsanActivity extends AppCompatActivity implements View.OnClickListener{

    private Button bindBtn;
    private Button jieBtn;
    private Button tiaoBtn;


    private String TAG="ZhangsanActivity";

    private ServiceConnection serviceConnection=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            Log.e("TAG","onServiceConnected*************###################");
            //通过管家的中介作用,拿到myService1对象
            MyService1 myService1 = ((MyService1.Guanjia) service).getServiceObject();
            myService1.fly();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.e("TAG","onServiceConnected*************###################");
        }
    };

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

        bindID();

    }

    private void bindID() {
        bindBtn=findViewById(R.id.bindBtn);
        jieBtn=findViewById(R.id.jiechuBtn);
        tiaoBtn=findViewById(R.id.tiao_lisi);

        bindBtn.setOnClickListener(this);
        jieBtn.setOnClickListener(this);
        tiaoBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.bindBtn:
                Intent intent=new Intent(this,MyService1.class);
                bindService(intent,serviceConnection,BIND_AUTO_CREATE);
                break;
            case R.id.jiechuBtn:
                unbindService(serviceConnection);
                break;
            case R.id.tiao_lisi:
                Intent intent1=new Intent(ZhangsanActivity.this,LisiActivity.class);
                startActivity(intent1);
                break;
        }
    }
}

使用intentservice的特点及优缺点

特点:
1.会创建独立的工作线程来处理所有的intent请求
2.会创建独立的工作线程来处理所有的onHandleIntent
3.多次调用,会按队列的顺序逐一执行

优点:
1.无需处理线程的创建与线程同步问题
2.无需手动关闭service
3.无需另开子线程

缺点:
无法精确线程的执行过程,一旦线程启动,只能等待线程执行完毕

intentservice的使用示例

先写一个MyIntentService继承IntentService,然后在onHandleIntent里面写一个for循环。重写onCreate、onDestroy两个方法。需要在创建一个无参的构造方法,因为那个是系统的。

public class MyIntentService extends IntentService {
    public MyIntentService(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {

        for (int i=0;i<5;i++){
            try {
                Log.e("MyIntentService",i+"***");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

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

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

然后就是添加button控件,最后需要绑定id,添加点击事件。在switch语句里面跳转。

public class ISActivity extends AppCompatActivity implements View.OnClickListener {
    private Button ISbtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_is);
        ISbtn = findViewById(R.id.is_btn);
        ISbtn.setOnClickListener(this);
    }

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

intentservice和service的区别

1.intentservice不要另开子线程,他可以按队列的顺序执行,而service不可以,执行耗时操作,需要开子线程
2.intentservice只能用startservice,而service可以有两种方式,但是每次也只能用一种
3.在manifest注册的时候,intentservice需要写一个无参的构造方法,而service不需要

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值