zoukankan      html  css  js  c++  java
  • 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");
            }
        }
    
    
    }
    

      

  • 相关阅读:
    Java在ACM中的应用
    acm->stl
    残缺棋盘--状压DP
    EOJ Monthly 2019.3 A
    【CF1141E】Superhero Battle
    AtCoder Grant Contest 10.F 博弈
    莫比乌斯反演总结
    P2257 YY的GCD
    BZOJ1011 莫比乌斯反演(基础题
    HDU1695 莫比乌斯反演
  • 原文地址:https://www.cnblogs.com/bugzone/p/android_service.html
Copyright © 2011-2022 走看看