后台Service简单使用

本文详细介绍了Android中的Service组件,包括Service的基本概念、生命周期方法、启动方式及绑定流程。通过具体的代码示例,帮助读者理解如何在应用中正确使用Service。

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

学习Service第一天,后头看之前写的那些博客   架构上还是有点不是很清晰,还是要把基础的调用分开写,然后再写项目代码,这样看起来会比较清晰

好了今天就先试验一下

进入主题,Android Service的使用,作为四大控件之一,Service还是很重要的。

1、Service可以理解为后台,何为后台,就是在界面没有任何显示的情况下,偷偷摸摸的干些事情。

2、Service在默认的情况下,还是属于主线程的!!!这点一定要注意,如果直接启动Service,并且让他做一些需要长期等待的工作,呵呵,不好意思UI界面直接无响应,所以一般Service都是的逻辑操作或者等待监听都是通过起一个线程,来解决的。

3、Service一定记得要在AndroidManifest注册,四大组件都要注册!!

简单注册代码

        <service android:name=".MyService">

        </service>


好了,接下来我们看一下,到底如何使用

一、使用Service必须使用一个类去继承Service

public class MyService extends Service
Service这个类,必须实现一个抽象方法

public IBinder onBind(Intent intent)
这个函数只有一个参数,我们来看一下解释

intent The Intent that was used to bind to this service
人工解释:这个Intent是被用来绑定这个Service的,什么意思。之后再启动Service的时候我会解释的

然后看返回值

Return an IBinder through which clients can call on to the service
人工解释(我猜了一些词,不一定完全准确,但是我知道他指的是啥,一会告诉大家):
当客户端让这个Service上线的时候,这个函数会返回一个IBinder类型的对象

这个在之后一会解释的

这样赤裸裸的一个类,就一个onBind方法,肯定是达不到我们的要求的,我们还需要重写他的一些父类方法

我这个实例,只是讲简单创建使用,所以都是伪逻辑,只是用Log打印说明方法被调用

看一下我们需要的方法

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

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

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("Service", "onDestroy");
    }
onCreate,onStartCommand,onDestroy,这不就是一个生命周期么

我已经测试过了,所以我们一个一个来看

onCreate方法,只有在这个服务第一次创建的时候,才会调用,注意Service的唯一性

onStartCommand方法,其实原来使用的onStart方法,只不过被Google淘汰了,但其实这个方法的内部逻辑,还是调用了onStart这个方法,具体可以自己看一下源码。这个方法里,之后会存放我们的主要逻辑。或者说在这里启动一个处理逻辑的线程。

onDestroy方法与OnCreate方法是一对,有创建才有销毁。

我们把方法介绍完了,就来看一下,如果启动一个Service

二、启动Service

我在MainActivity创建了4个Button控件,两两一对,用来匹配启动Service的两种方法

<?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: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"
    android:orientation="vertical"
    tools:context="com.tyran.frontservice_demo1.MainActivity">

    <Button
        android:id="@+id/StartService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/start_service"
        android:onClick="OnClick"/>

    <Button
        android:id="@+id/StopService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/stop_service"
        android:onClick="OnClick"/>

    <Button
        android:id="@+id/BindService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/bind_service"
        android:onClick="OnClick"/>

    <Button
        android:id="@+id/UnBindService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/unbind_service"
        android:onClick="OnClick"/>
</LinearLayout>
第一种方法,通过startService和stopService来控制Service

这两个方法都只有一个参数Intent,那这个Intent该如何初始化呢

VeryEasy

        intent = new Intent(this, MyService.class);
        intent.putExtra("Flag", "100");
MyService就是Service的子类

那之后的putExtra的作用是什么呢?

还记得之前的onBind方法么,我现在可以告诉你,这个Intent就是之后就会被传到onBind方法的Intent,所以我在这里添加了一个标记数据,之后我会在onBind里取出并打印。这里先提一下,在之后的第二种方法里我会重新解释一下。

既然Intent已经有了,那无非就是绑定控件,一个switch

            case R.id.StartService:
                startService(intent);
                break;
            case R.id.StopService:
                stopService(intent);
                break;
当我点击StartService这个按钮时,看一下Log输出

D/Service: onCreate
D/Service: onStartCommand

点击StopService

D/Service: onDestroy
我连续点击两下StartService

D/Service: onCreate
D/Service: onStartCommand
D/Service: onStartCommand

验证了我之前的说法,onCreate方法只会执行一次

大家注意到,Log里没有出现onBind的信息,但是我在onBind里是会打印Log的呀,并且在应用管理器中,能看到MyService这个服务的运行状态为启动。我们唯一要实现的方法居然没有调用,这肯定是不行的。那如何解决呢?

看我们的第二种方法

也是一对方法bindService和unbindService

public boolean bindService(Intent service, ServiceConnection conn, int flags)
public void unbindService(ServiceConnection conn)
绑定和解除绑定

看了方法定义我们会发现多了一个ServiceConnection,而且之前我们并没有创建或者使用过,这个类型,那我们就创建一个

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            binder = (MyService.MyBinder) service;
            binder.BindNotification();
            Log.d("Service", "onServiceConnected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("Service", "onServiceDisconnected");

        }
    };
创建之后,貌似就明了了,一个连接一个断开连接,并且这个IBinder貌似也似曾相识,不就是onBind的返回值么

查看一下源码,发现IBinder是一个接口,那必然需要一个实现类

在MyService里创建一个类

    public class MyBinder extends Binder
    {
        public void BindNotification()
        {
            Log.d("Service", "MyBinder");
        }
    }
并且我把onBind的代码也贴一下

    MyBinder binder = new MyBinder();
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d("Service", "onBind");
        Log.d("Service", "Intent"+intent.getStringExtra("Flag"));
        return binder;
    }
对比一下,onServiceConnected的方法,第二个形参,在看一下onBind的解释,会返回一个IBinder,

经过测试,原来onBind方法的返回值,就是回传到onServiceConnected方法的第二个形参。既然是传递,自然要有实体,我们构造的MyBinder类自然要在MyService里构造对象,然后MyBinder通过onBind传递给onServiceConnected,是不是突然之间思路就清晰了

MyBinder->onBind->onServiceConnected就是这样一个过程,在MyBinder里只有一个打印Log的方法,虚拟一下逻辑

好了,陌生的讲完,我们回过头看onBind的参数Intent,前面已经说过回传这个事情了,这个自然也能联想到,bindService的第一个形参,对,你猜对了,这也是一个传参,具体我就不解释啦,上面onBind的代码已经写得很清楚啦,注意第二条打印Log即可。就剩下bindService的第三个参数了,这个其实就是个标记,BIND_AUTO_CREATE代表绑定服务时如果服务未创建,自动创建,怎么创建呢,就是调用Service类的onCreate

unbindService唯一的一个参数,就是ServiceConnection这个没啥好说的。我重新理一下顺序

bindService->ServiceConnection.onServiceConnected->onCreate

我再把第一种写一下

startService->onCreate->onStartCommand

实际的应用场景,其实我也不是很明白,之后肯定会有实际应用的例子补充,以后再说啦

接下来就是完整代码

首先是AndroidManifest

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        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">

        </service>
    </application>

</manifest>
然后是MainActivity的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: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"
    android:orientation="vertical"
    tools:context="com.tyran.frontservice_demo1.MainActivity">

    <Button
        android:id="@+id/StartService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/start_service"
        android:onClick="OnClick"/>

    <Button
        android:id="@+id/StopService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/stop_service"
        android:onClick="OnClick"/>

    <Button
        android:id="@+id/BindService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/bind_service"
        android:onClick="OnClick"/>

    <Button
        android:id="@+id/UnBindService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/unbind_service"
        android:onClick="OnClick"/>
</LinearLayout>
MainActivity

package com.tyran.frontservice_demo1;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    Intent intent;
    private MyService.MyBinder binder;
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            binder = (MyService.MyBinder) service;
            binder.BindNotification();
            Log.d("Service", "onServiceConnected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("Service", "onServiceDisconnected");

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent(this, MyService.class);
        intent.putExtra("Flag", "100");
    }

    public void OnClick(View v)
    {
        switch (v.getId())
        {
            case R.id.StartService:
                startService(intent);
                break;
            case R.id.StopService:
                stopService(intent);
                break;
            case R.id.BindService:
                bindService(intent,connection,BIND_AUTO_CREATE);
                break;
            case R.id.UnBindService:
                unbindService(connection);
                break;
        }
    }
}
MyService

package com.tyran.frontservice_demo1;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

/**
 * Created by Tyran on 2017/2/27.
 */

public class MyService extends Service {
    MyBinder binder = new MyBinder();
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d("Service", "onBind");
        Log.d("Service", "Intent"+intent.getStringExtra("Flag"));
        return binder;
    }

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

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

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

    public class MyBinder extends Binder
    {
        public void BindNotification()
        {
            Log.d("Service", "MyBinder");
        }
    }
}
这样完整的看一遍,应该基本的使用应该就都明白了吧。回头我也自己多看看  哈哈哈



















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值