【Android】四大组件之Service

Service是Android四大组件之一,主要用于在后台处理一些耗时的逻辑,或去执行一些需要长期运行的任务。有时候我们甚至可以在程序退出的情况下,让Service继续保持运行的状态。

创建Service

要创建Service,我们可以在Android Studio中右键项目栏,选择new->Service来创建,也可以自己新建一个Java类,继承自Service来创建。不过要注意的是,项目中的每一个Service都必须在AndroidManifest.xml中注册才行 。如果是由Android Studio替我们创建,会自动为我们注册。如果是手动创建,需要用如下的方式手动注册:

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

启动与停止Service

启动和停止Service的方法和启动Activity很类似,都需要借助Intent来实现 。

启动Service

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

停止Service

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

停止Service除了这种方式,还可以由Service自己停止自己,只需要在其任意位置调用stopSelf()方法,就能让它停下来了。

使用Service

当我们调用startCommand方法后,Service会在内部调用onCreate方法以及onStartCommand方法。因此,我们可以将创建Service后的一些逻辑写在onCreate方法中,将一些Service需要执行的逻辑放在onStartCommand中。

使用Service主要是用于处理一些后台的耗时逻辑或需要长期运行的任务。因此服务应该运行于独立于主线程的另一线程。但是需要注意的是,实际上服务并不会自动开启新线程,所有代码是默认都在主线程中运行的。因此,我们需要在其内部手动创建子线程,否则可能出现主线程被阻塞的情况。

Activity与Service通信

可以发现,虽然Service是在Activity中启动,但启动后,它们看上去之间就没有什么关系了。Service会一直处于运行状态跟,但具体的运行逻辑Activity就无法控制了。因此我们可以通过onBind方法来实现。

Service部分

我们可以在Service内部创建一个继承自Binder的类,在它内部提供实现具体逻辑的方法。然后在Service类中创建一个该Binder的实例,并在onBind方法中返回。

public class downloadService extends Service{
    private DownloadBinder mBinder = new DownloadBinder();

    class DownloadBinder extends Binder{
        public void startDownload(){
            //start download
        }

        public void stopDownload(){
            //stop download
        }
    }

    @Override
    public IBinder onBind(Intent intent){
        return mBinder;
    }
}

Activity部分

首先,我们可以在Activity中声明一个Binder对象,并创建一个ServiceConnection对象,实现它的onServiceConnected以及onServiceDisconnected两个方法。我们可以在onServiceConnected方法中将参数中的IBinder对象强转为我们的Binder,并赋值给我们的Binder对象。

然后我们可以像前文一样创建一个Intent,然后用bindService方法,传入intent,之前创建的connection,以及一个标志位。这样就成功绑定了Activity与Service。(传入BIND_AUTO_CREATE会在Activity和Service绑定后自动创建服务,这使得onCreate方法执行,而onStartCommand方法不执行)

而要解绑Activity与Service的话,就只需要调用unbindService并传入相应connection即可。

Service的生命周期

在Service的生命周期中,常用的有如下:

4个手动调用的方法

  • startService:用于启动服务,手动调用startService()后,自动调用内部方法:onCreate()、onStartCommand()

  • stopService:用于关闭服务,手动调用stopService()后,自动调用内部方法:onDestory()

  • bindService:用于绑定服务,手动调用bindService()后,自动调用内部方法:onCreate()、onBind()
  • unbindService:用于解绑服务,手动调用unbindService()后,自动调用内部方法:onCreate()、onBind()、onDestory()

5个内部调用的方法

  • onCreate:创建服务
  • onStartCommand:开始服务
  • onDestroy:销毁服务
  • onBind:绑定服务
  • onUnbind:解绑服务

前台Service

有时候因为一些特殊需求或为了防止因系统内存不足而将Service回收,我们可以使用前台Service。

要创建前台Service,我们只用在服务的onCreate方法中创建一个Notficiation,再调用其startForeground方法即可。例如:

@Override
public void onCreate(){
    super.onCreate();
    Notification notification = new NotificationCompat.Builder(this)
        .setContentTitle("Title")
        .setContentText("This is a content text")
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.mipmap.ic_launcher)
        .build();
    startForeground(1,notification);
}

startForeground方法的两个参数中,第一个参数是通知的id,第二个参数则是Notfication对象。调用了startForeground方法后,就会让这个Service变成一个前台的Service,并在系统状态栏显示出来。

N0tExpectErr0r

N0tExpectErr0r

一名热爱代码的 Android 开发者

留下你的评论

*评论支持代码高亮<pre class="prettyprint linenums">代码</pre>