《Android 第一行代码》十一章 Service学习笔记

Android中Service学习笔记

Service的基本使用方法
Service的启动方式有两种,第一种是使用startService()和stopService()方法来启动和停止Service;第二种是使用bindService()方法来绑定Service(此方法可以随时获取Service的执行状态和参数)。

1. 注意要点:

  1. startService()之后,onCreate()只执行一次,在Service没有被创建时候,执行创建。此后再运行startService()方法,都只执行onStartCommand()方法。当执行stopService()或者在Service中任何地方调用自身的stopSelf()方法后,服务将停止。此后再次调用stopService()方法,将不再起作用,也不报错。执行过程:startService()——>onCreate()——>onStartCommand()——>stopService()——>onDestory();其中startService()和stopService()在Activity()中调用的,其他为Service()里面的方法。
  2. 第二种方式是使用bindService()方法来绑定运行Service,使用unbindService()来解绑停止Service()。使用此方法更加复杂一些,bindService()参数有三个,分别为intent,serviceConnection和常数。一般需要新建一个ServiceConnection来进行连接。 此处注意: unbindService()只执行一次,解绑后再次调用unbindService()方法会报错。执行过程:bindService()——>onBind()——>onUnbind()——>unbindService()——>onDestory()。
  3. 此外,两种方式可以混合一起使用,当一起使用时,如果启动Service的方法即使用startService()用使用了bindService()那么,停止服务时也必须搭配使用stopService()和unbindService()方法。

2. service的具体实现

  • 第一步:新建一个MyService 继承Service类,并覆写onStartCommand方法。
  • 第二步:启动Service,使用startService()或者bindService()方法。
  • 第三步:调用停止Service的方法。

3. 使用bindService()方法来实现与Service()之间的通信
要实现Context与Service通信,需要使用bindService()方式启动Service()。下面以一个简单的下载服务为实例回顾一下Service()通信的具体流程。

  • 第一步:需要新建MyService()继承Service基类,覆写onBind()方法。
  • 第二步:在MyService()类中新建MyBinder内部类,继承Binder基类。在此类中定义自己的方法,此处定义两个方法:startDownload(),getProgress()方法,分别用来启动下载和获取下载进度。
  • 第三步: 在MyService()类中的onBind()方法中返回一个Mybinder类的实例。这个实例会在前台定义ServiceConnection类中的onServiceConnected中作为方法参数传递到前台。前台可以通过此类对象调用MyBinder类中的方法。
  • 第四步:在前台首先定义一个ServiceConnection类,覆写onServiceConnected()方法,在此方法中获取实例MyBinder类实例,并调用它的.startDownload()和.getProgress()方法。
  • 第五步:调用bindService()方法,传递参数为intent,connection,BIND_AUTO_CREATE 。且解绑参数是传递ServiceConnection实例即可。

以下为代码实例:
MyService.class

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

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

    class MyBinder extends Binder {
        //定义两个方法,会传递到前台被调用
        public void startDownload() {
            //开启下载
        }

        public int getProgress() {
            return 0;
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //此方法里面是使用startService()方法之后执行的,且不做交互
        return super.onStartCommand(intent, flags, startId);
    }

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

Main2Activity.class

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

public class Main2Activity extends AppCompatActivity {

    private Button mButton;
    private Button mStopService;
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            MyService2.MyBinder mBinder = (MyService2.MyBinder) iBinder;
            mBinder.startDownload();
            mBinder.getProgress();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            //断开连接,回收资源
        }
    };

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

        mButton = (Button) findViewById(R.id.start_service);
        mStopService = (Button) findViewById(R.id.stop_service);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //绑定Service()
                Intent intent = new Intent(getApplication(), MyService2.class);
                bindService(intent, mConnection, BIND_AUTO_CREATE);
            }
        });

        mStopService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                unbindService(mConnection);     //解绑,直接传递ServiceConnection即可,不必要传递Intent
            }
        });
    }
}

接下来,我们学习了前台服务。前台服务和后台服务相比,优先级更高,不易于被系统回收而杀死。前台服务的一个特点就是,在手机通知栏会显示一个服务的通知,像音乐播放器、下载进度等。下面来学习一个简单的前台服务。

4. 前台服务
只需要将一个Activity绑定到一个Service中就可以得到前台服务。新建Intent,将Intent放入PendingIntent中,然后新建Notification notification=new NotificationCompat.Builder(this).set()….setContentIntent(pi)等参数。之后使用startForeground(1,notification)方式启动即可。

5. IntentService介绍
我们一般使用Service,都需要做一些耗时任务。然而Service也是运行在UI线程里面的,因此一般需要在Service里面开启线程。然而,很多时候,我们开启线程之后,很容易忘记去关闭线程,而且使用起来也比较麻烦。所以Android推出了IntentService类,继承的Service。主要是用来结果我们这个问题的。
IntentService中自带有一个抽象方法需要覆写onHandIntent()方法,此方法都是执行在子线程中的,且代码执行完后会自动结束。这些是IntentService底层封装好的。
注意: 在调用startService(IntentService)后,onHandIntent()会执行多次,以消息队列的方式依次执行。

Service和IntentService基础就介绍到这里,下面通过一个具体的下载实例来复习和巩固知识点。

你可能感兴趣的:(学习随笔)