Android 四大组件 (二) Service 使用

一. Service 介绍

Service属于android四大组件之一,在很多地方经常被用到。开启Service有两种不同的方式:startService和bindService。不同的开启方式,Service执行的生命周期方法也不同。

分 显示/隐示调用 ,但是官网推荐用显式的方式启动Service。下面 service使用 用的就是显示调用;注意事项用的就是隐示调用,在5.0系统上隐示调用会报错。所以这里只介绍使用显示调用。

不能再service里做耗时操作,否则ANR;需要开辟子线程进行耗时操作处理。

二.Service 使用

  1.startService使用。

Intent intent = new Intent(this, TestService.class);
Log.w(Tag, "activity====启动服务");
startService(intent);

执行效果:

 

Log.w(Tag, "activity====停止服务");
stopService(intent);

执行效果:   

 

 

   2.bindService绑定.

private class MyConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //只有当我们自己写的MyService的onBind方法返回值不为null时,才会被调用
            Log.e("call", "onServiceConnected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // 这个方法只有出现异常时才会调用,服务器正常退出不会调用。
            Log.e("call", "onServiceDisconnected");
        }
    }

 

Log.w(Tag, "activity====绑定服务");
MyConnection conn = new MyConnection();
//第一个参数:Intent意图
// 第二个参数:是一个接口,通过这个接口接收服务开启或者停止的消息,并且这个参数不能为null
 // 第三个参数:开启服务时的操作,BIND_AUTO_CREATE代表自动创建service bindService(service, conn, BIND_AUTO_CREATE);
 bindService(intent, conn, BIND_AUTO_CREATE);

 

  执行效果:

 

Log.w(Tag, "activity====解绑服务");
unbindService(conn);

  执行效果:

 

 

   3.区别:

 以下摘自网络,后续验证

 服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。
 
 使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
 
如果打算采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
 
如果打算采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。

 

三.Service 注意事项:

在5.0系统上使用如下方式start或者bind启动service时候:

Intent intent = new Intent();  
intent.setAction("com.example.user.firstapp.FIRST_SERVICE");  
bindService(intent,coon,Service.BIND_AUTO_CREATE);  

startService(intent);

  

android 5.0上,报错:IllegalArgumentException: Service Intent must be explicit

原因是:Android5.0中service的intent一定要显性声明!!!

 

四.附上核心activity代码:

package com.example.hp.testapp;

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;
import android.widget.TextView;

import com.example.hp.testapp.service.TestService;

import org.w3c.dom.Text;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private String Tag = "TestServiceTag";

    private TextView tv_btn_start;
    private TextView tv_btn_stop;
    private TextView tv_btn_bind;
    private TextView tv_btn_unbind;

    Intent intent;
    MyConnection conn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent(this, TestService.class);
        conn = new MyConnection();
        initView();
        initListener();
    }

    private void initView() {
        tv_btn_start = (TextView) findViewById(R.id.tv_btn_start);
        tv_btn_stop = (TextView) findViewById(R.id.tv_btn_stop);
        tv_btn_bind = (TextView) findViewById(R.id.tv_btn_bind);
        tv_btn_unbind = (TextView) findViewById(R.id.tv_btn_unbind);
    }

    private void initListener() {
        tv_btn_start.setOnClickListener(this);
        tv_btn_stop.setOnClickListener(this);
        tv_btn_bind.setOnClickListener(this);
        tv_btn_unbind.setOnClickListener(this);
    }


    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.tv_btn_start:
                /**
                 * 启动服务
                 */
                Log.w(Tag, "activity====启动服务");
                startService(intent);
                break;
            case R.id.tv_btn_stop:
                /**
                 * 停止服务
                 */
                Log.w(Tag, "activity====停止服务");
                stopService(intent);
                break;
            case R.id.tv_btn_bind:
                /**
                 * 绑定服务
                 */
                Log.w(Tag, "activity====绑定服务");
                //第一个参数:Intent意图
                // 第二个参数:是一个接口,通过这个接口接收服务开启或者停止的消息,并且这个参数不能为null
                // 第三个参数:开启服务时的操作,BIND_AUTO_CREATE代表自动创建service bindService(service, conn, BIND_AUTO_CREATE);
                bindService(intent, conn, BIND_AUTO_CREATE);
                break;
            case R.id.tv_btn_unbind:
                /**
                 * 解绑服务
                 */
                Log.w(Tag, "activity====解绑服务");
                if (conn != null) {
                    unbindService(conn);
                }
            default:
                break;
        }
    }

    @Override
    protected void onStart() {
        Log.w(Tag, "activity====onStart");
        super.onStart();
    }

    @Override
    protected void onRestart() {
        Log.w(Tag, "activity====onRestart");
        super.onRestart();
    }

    @Override
    public void onStateNotSaved() {
        Log.w(Tag, "activity====onStateNotSaved");
        super.onStateNotSaved();
    }

    @Override
    protected void onResume() {
        Log.w(Tag, "activity====onResume");
        super.onResume();
    }

    @Override
    protected void onPause() {
        Log.w(Tag, "activity====onPause");
        super.onPause();
    }

    @Override
    protected void onStop() {
        Log.w(Tag, "activity====onStop");
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        Log.w(Tag, "activity====onDestroy");
        super.onDestroy();
    }

    private class MyConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //只有当我们自己写的MyService的onBind方法返回值不为null时,才会被调用
            Log.e("call", "onServiceConnected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // 这个方法只有出现异常时才会调用,服务器正常退出不会调用。
            Log.e("call", "onServiceDisconnected");
        }
    }


}

  

posted @ 2018-05-13 23:46  FreeFunCode  阅读(761)  评论(0编辑  收藏  举报