Android-Service

179 阅读4分钟

1.通过startService启动service

通过startService启动的service会一直运行下来,只有在调用stopservice(),stopself()才会停止并销毁。内存不足的时候系统也会根据service的优先级杀死非系统的service。
stopservice():调用后不会立刻执行onDestroy(),只有等到onStartCommand()和onCreate()的功能完成后比如线程走完才会停止。
stopself():执行后会立即停止service,调用onDestroy()。

  • AndroidManifest中注册service(不管哪种方式都必须要注册)
    <service android:name=".service.NetworkStateService" />
  • 自定义类继承service,重写下面几个方法:
    -onCreate():只有在第一次调用startService()的时候会调用,只要该Service没有销毁之前无论调用多少次startService都不会再走,所以在这里可以做一些初始化的事。
    -onStartCommand():调用几次startService()就会走几次这个方法。
    -onBind():该方法只有在BindService()的时候有用
    -onDestroy():摧毁service时调用。
  • 
      @Override
      public void onCreate() {
          Log.i("Kathy","onCreate); //打印所在线程
          super.onCreate();
      }
    
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
          Log.i("Kathy", "onStartCommand);
          return super.onStartCommand(intent, flags, startId);
      }
    
      @Nullable
      @Override
      public IBinder onBind(Intent intent) {
          Log.i("Kathy", "onBind);
          return null;
      }
    
      @Override
      public void onDestroy() {
          Log.i("Kathy", "onDestroy);
          super.onDestroy();
      }
    

2.通过bindService()启动service

  • 通过bindService启动的服务跟调用者之间是client-server的模式,调用者是client,service是server。service只有一个,而client可以有多个,通过bindService绑定在service上,这里的client代表是组件。
  • 在组件里可以通过IBinder获取service实例,从而进行交互。
  • 通过bindService启动的service其生命周期跟改组件是一致的,也就是说改组件销毁service也就会销毁,也可以调用onUnBindService()解绑关闭。不过这里service的销毁并不会一定会走onDestroy()。之前提到service可以绑定多个client,所以这里在调用onUnBindService后,系统会去查找确保该service上没有绑定的client后才会走onDestrody()回掉。

要想让Service支持bindService调用方式,需要做以下事情:
service:
1.在Service的onBind()方法中返回IBinder类型的实例。

2.onBInd()方法返回的IBinder的实例需要能够返回Service实例本身。通常,最简单的方法就是在service中创建binder的内部类,加入类似getService()的方法返回Service,这样绑定的client就可以通过getService()方法获得Service实例了。 client:
client端要做的事情: 1.创建ServiceConnection类型实例,并重写onServiceConnected()方法和onServiceDisconnected()方法。

2.当执行到onServiceConnected回调时,可通过IBinder实例得到Service实例对象,这样可实现client与Service的连接。

3.onServiceDisconnected回调被执行时,表示client与Service断开连接,在此可以写一些断开连接后需要做的处理。(这里在连接正常关闭的情况下是不会被调用的, 该方法只在Service 被破坏了或者被杀死的时候调用. 例如, 系统资源不足, 要关闭一些Services, 刚好连接绑定的 Service 是被关闭者之一, 这个时候onServiceDisconnected() 就会被调用)

public class TestTwoService extends Service{

    //client 可以通过Binder获取Service实例
    public class MyBinder extends Binder {
        public TestTwoService getService() {
            return TestTwoService.this;
        }
    }

    //通过binder实现调用者client与Service之间的通信
    private MyBinder binder = new MyBinder();

    private final Random generator = new Random();

    @Override
    public void onCreate() {
        Log.i("Kathy","TestTwoService - onCreate - Thread = " + Thread.currentThread().getName());
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("Kathy", "TestTwoService - onStartCommand - startId = " + startId + ", Thread = " + Thread.currentThread().getName());
        return START_NOT_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.i("Kathy", "TestTwoService - onBind - Thread = " + Thread.currentThread().getName());
        return binder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.i("Kathy", "TestTwoService - onUnbind - from = " + intent.getStringExtra("from"));
        return false;
    }

    @Override
    public void onDestroy() {
        Log.i("Kathy", "TestTwoService - onDestroy - Thread = " + Thread.currentThread().getName());
        super.onDestroy();
    }

    //getRandomNumber是Service暴露出去供client调用的公共方法
    public int getRandomNumber() {
        return generator.nextInt();
    }
}

client的代码:

public class ActivityA extends Activity implements Button.OnClickListener {
    private TestTwoService service = null;
    private boolean isBind = false;

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            isBind = true;
            TestTwoService.MyBinder myBinder = (TestTwoService.MyBinder) binder;
            service = myBinder.getService();
            Log.i("Kathy", "ActivityA - onServiceConnected");
            int num = service.getRandomNumber();
            Log.i("Kathy", "ActivityA - getRandomNumber = " + num);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isBind = false;
            Log.i("Kathy", "ActivityA - onServiceDisconnected");
        }
    };

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_a);
        Log.i("Kathy", "ActivityA - onCreate - Thread = " + Thread.currentThread().getName());

        findViewById(R.id.btnBindService).setOnClickListener(this);
        findViewById(R.id.btnUnbindService).setOnClickListener(this);
        findViewById(R.id.btnStartActivityB).setOnClickListener(this);
        findViewById(R.id.btnFinish).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btnBindService) {
            //单击了“bindService”按钮
            Intent intent = new Intent(this, TestTwoService.class);
            intent.putExtra("from", "ActivityA");
            Log.i("Kathy", "----------------------------------------------------------------------");
            Log.i("Kathy", "ActivityA 执行 bindService");
            bindService(intent, conn, BIND_AUTO_CREATE);
        } else if (v.getId() == R.id.btnUnbindService) {
            //单击了“unbindService”按钮
            if (isBind) {
                Log.i("Kathy",
                        "----------------------------------------------------------------------");
                Log.i("Kathy", "ActivityA 执行 unbindService");
                unbindService(conn);
            }
        } else if (v.getId() == R.id.btnStartActivityB) {
            //单击了“start ActivityB”按钮
            Intent intent = new Intent(this, ActivityB.class);
            Log.i("Kathy",
                    "----------------------------------------------------------------------");
            Log.i("Kathy", "ActivityA 启动 ActivityB");
            startActivity(intent);
        } else if (v.getId() == R.id.btnFinish) {
            //单击了“Finish”按钮
            Log.i("Kathy",
                    "----------------------------------------------------------------------");
            Log.i("Kathy", "ActivityA 执行 finish");
            this.finish();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("Kathy", "ActivityA - onDestroy");
    }
}

3.生命周期:

1)启动Service服务

单次startService():onCreate() —> onStartCommand()
多次startService():onCreate() —> onStartCommand() —> onStartCommand()
2)停止Service服务
stopService(): onDestroy()
3)绑定Service服务
bindService(): onCreate() —> onBind()
4)解绑Service服务
unbindService(): onUnbind() —> onDestroy()
5)启动绑定Service服务
startService(): onCreate() —> onStartCommand() —> bindService() —> onBind()

感谢:www.jianshu.com/p/4c798c91a… 方便以后查阅