一、什么是Service?

Service是一个可以在后台长时间运行操作而且没有用户界面的组件。它是运行在主线程中的,所以不能在Service中执行耗时操作。它可以由其他组件来启动,比如activity或者broadcast,服务一旦启动,就会一直在后台运行,即使启动它的组件被销毁了,也不会影响它的运行。我们可以把service和activity进行绑定,这样就可以实现两者之间的数据交互。

二、service和thread的区别?

  • 定义:thread是程序运行的最小单元,我们可以通过开启子线程来完成一些耗时操作,而service是后台服务,是安卓中的一种机制,如果是本地的service,那么它就运行在它所在的主线程,所以service中不能进行耗时操作。
  • 实际开发:不能在service中进行耗时操作,如果一定要进行,那么也必须要开启子线程,那为什么不在activity中开启子线程呢?因为activity很难对子线程进行把控,一旦activity销毁了,那么将很难获得子线程的实例,容易造成内存泄漏。而service不一样,即使activity被销毁了,service依然可以在后台执行。
  • 应用场景:如果我们需要进行耗时操作,那么就必须要开启子线程。而service是需要长时间在后台运行,并且不需要用户界面的情况下才会使用,比如后台播放音乐,天气预报的统计等。

三、service的两种启动方式以及区别?

  • startService:通过此种方式启动的服务,会一直在后台运行,除非手动关闭。
  • 执行步骤如下:
  • 1、定义一个类继承service;
  • 2、在manifest.xml文件中注册service;
  • 3、使用context的startService()启动服务;
  • 4、如果不再使用,调用stopService()方法来停止该服务。
  • bindService:此时service和activity处于绑定状态,两者之间可以进行数据交互。
  • 执行步骤如下:
  • 定义一个服务端继承service,并且在类中实现IBinder接口的实例对象,并提供公共方法给客户端调用;
  • 在onBind()方法中返回此Binder实例;
  • 客户端在onServiceConnected()方法中接收Binder实例,并通过服务端提供的方法绑定服务。

接下来通过代码来深刻理解两种启动service的方法到底什么区别。

  • 首先是startService
public class StartService extends Service {
    private static final String TAG = "StartService";

    /**
 * 首次创建服务时,系统将调用此方法执行一次性设置程序(在调用onStartCommand()或者onBind()之前),
 * 如果服务已在运行,则不会调用此方法,该方法只被调用一次。
 */

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "StartService Thread id is ==="+Thread.currentThread().getId() );
    }

    /**
 * 绑定服务的时候才会调用
 * 必须要实现的方法
 * @param intent
 * @return
 */

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

    /**
 * 每次通过startService()启动Service时都会被回调。
 * @param intent
 * @param flags
 * @param startId
 * @return return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;
 * 如果返回START_STICKY,那么在系统内存空暇时,系统会尝试重新启动服务,而此时的intent为null;
 */

    @Override
    public int onStartCommand(Intent intent,  int flags, int startId) {
        System.out.println("onStartCommand invoke");

        Log.e(TAG, "StartService Thread id is ==="+Thread.currentThread().getId() );

        return super.onStartCommand(intent, flags, startId);
    }

    /**
 * 服务销毁时的回调
 */

    @Override
    public void onDestroy() {
        System.out.println("onDestroy invoke");
        super.onDestroy();
    }
}
  • 1
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private Button mBtStop,mBtStart,mBtBind;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBtStart= (Button) findViewById(R.id.btn_start);
        mBtStop= (Button) findViewById(R.id.btn_stop);

        Log.e(TAG, "MainActivity thread id is=="+Thread.currentThread().getId() );

        final Intent intent=new Intent(MainActivity.this,StartService.class);

        mBtStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startService(intent);
            }
        });

        mBtStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopService(intent);
            }
        });



    }
}
  • 1

-接下来是bindService

public class BindService extends Service {

    private static final String TAG = "BindService";
    private LocalBinder binder=new LocalBinder();
    private int count;
    private Thread thread;
    private boolean quit;

    /**
 * 创建Binder对象,返回给客户端的Activity使用,提供数据交接的接口
 */
    public class LocalBinder extends Binder{
        //申明一个方法getService(),提供给客户端调用
        BindService getService(){
            //返回当前对象LocalBinder,这样我们就可以在客户端调用Service的公共方法了。
            return BindService.this;
        }
    }

    /**
 * 把Binder类返回给客户端
 * @param intent
 * @return
 */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "Service is invoke Created" );
        thread =new Thread(new Runnable() {
            @Override
            public void run() {
                while (!quit){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count++;
                }
            }
        });
        thread.start();

    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "Service is invoke Destroyed" );
        this.quit=true;
        super.onDestroy();
    }

    /**
 * 公共方法
 * @return
 */
    public int getCount(){
        return count;
    }

    /**
 * 解除绑定时调用
 * @param intent
 * @return
 */
    public boolean onUnbind(Intent intent){
        Log.e(TAG, " Service is invoke onUnbind" );
        return super.onUnbind(intent);
    }

}
  • 1
public class BindActivity extends AppCompatActivity {
    private static final String TAG = "BindActivity";

    private Button btnBind,btnUnBind,btnGetDatas;

    private BindService mService;
    private ServiceConnection conn;

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

        btnBind= (Button) findViewById(R.id.btn_Bind);
        btnUnBind= (Button) findViewById(R.id.btn_UnBind);
        btnGetDatas= (Button) findViewById(R.id.btn_GetDatas);

        //创建绑定对象
        final Intent intent=new Intent(this,BindService.class);

        //开启绑定
        btnBind.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "绑定调用:bindService" );
                bindService(intent,conn, Service.BIND_AUTO_CREATE);
                Log.e(TAG, "绑定成功");
            }
        });

        //解除绑定
        btnUnBind.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "解除绑定调用:unbindService" );
                if(mService!=null){
                    mService=null;
                    unbindService(conn);
                }
            }
        });

        //获取数据
        btnGetDatas.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mService!=null){
                    //通过绑定服务传递的Binder对象,获取Service暴露出来的数据
                    Log.e(TAG, "从服务器获取数据 "+mService.getCount() );
                }else {
                    Log.e(TAG, "还没有进行绑定,请先绑定");
                }
            }
        });

        /**
 * ServiceConnection代表与服务器的连接,它只有两个方法
 * @param savedInstanceState
 */
        conn=new ServiceConnection(){

            /**
 * 与服务器交互的接口方法,绑定服务的时候被回调,在这个方法中获取绑定Service 传递过来的IBinder对象
 * 通过这个IBinder对象,实现宿主与Sevice的交互
 * @param name
 * @param service
 */
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.e(TAG, "绑定成功调用 onServiceConnected");
                BindService.LocalBinder binder= (BindService.LocalBinder) service;
                mService=binder.getService();
            }

            /**
 * 当取消绑定的时候被回调,但正常情况下式不会被回调的,只有当Service服务被意外销毁时
 * 例如内存不足时这个方法才会被自动调用
 * @param name
 */
            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.e(TAG, "绑定失败调用 onServiceDisconnected");
            }
        };

    }

}