美文网首页
Android四大组件——Service

Android四大组件——Service

作者: shawXXQ | 来源:发表于2017-10-01 16:23 被阅读0次

    Service的生命周期与启动/停止服务

    timg.jpg
    public class MyService extends Service {
        private final static String TAG = "MyService";
    
        public MyService() {
        }
        
        //服务被创建时调用
        @Override
        public void onCreate() {
            super.onCreate();
            Log.d(TAG, "onCreate");
        }
    
        //服务被启动时调用
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.d(TAG, "onStartCommand");
            return super.onStartCommand(intent, flags, startId);
        }
    
        //服务被销毁时调用
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.d(TAG, "onDestroy");
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
            throw new UnsupportedOperationException("Not yet implemented");
        }
    }
    
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.start_service:
                    Intent startIntent = new Intent(this, MyService.class);
                    //启动服务
                    startService(startIntent);
                    break;
                case R.id.stop_service:
                    Intent stopIntent = new Intent(this, MyService.class);
                    //停止服务
                    stopService(stopIntent);
                    break;
                default:
                    break;
            }
        }
    

    启动服务后的日志为

    图片.png

    当再次点击启动服务按钮时,日志为

    图片.png

    可以看出onCreate()方法不再执行,即onCreate()方法只会在服务第一次被创建的时候执行。
    点击停止服务的按钮时,日志为

    图片.png

    即onDestory()方法被执行

    在Service中调用stopSelf()方法也可以停止服务


    Activity与Service通信

    Service代码

        //Activity与Service通信时使用
        @Override
        public IBinder onBind(Intent intent) {
            Log.d(TAG, "onBind");
            return mBinder;
        }
    
        private DownloadBinder mBinder = new DownloadBinder();
    
        class DownloadBinder extends Binder {
            public void startDownload() {
                Log.d(TAG, "startDownload");
            }
    
            public int getProcess() {
                Log.d(TAG, "getProcess");
                return 0;
            }
        }
    

    Activity代码

        private MyService.DownloadBinder downloadBinder;
    
        private ServiceConnection connection = new ServiceConnection() {
            @Override
            //Activity与Service绑定成功时调用
            public void onServiceConnected(ComponentName componentName, IBinder service) {
                //向下转型得到DownloadBinder实例,该实例可以调用DownloadBinder的public方法
                downloadBinder = (MyService.DownloadBinder) service;
                downloadBinder.startDownload();
                downloadBinder.getProcess();
            }
    
            //Activity与Service解除绑定时调用
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
            }
        };
    
                case R.id.bind_service:
                    Intent bindIntent = new Intent(this, MyService.class);
                    /**
                     * 绑定服务,第一个参数为Intent对象,
                     * 第二个参数为ServiceConnection对象
                     * 第三个参数为flag标识,BIND_AUTO_CREATE表示自动创建service,
                     * 此时onCreate()方法执行,onStartCommand()方法不会执行
                     */
                    bindService(bindIntent, connection, BIND_AUTO_CREATE);
                    break;
                case R.id.unbind_service:
                    //解除绑定
                    unbindService(connection);
                default:
                    break;
    

    日志打印结果为

    图片.png

    即绑定服务时onBind()方法会被调用,且通过其返回一个Binder对象给Activity,从而在Activity中通过对象转型来调用Service中的方法

    点击解除绑定按钮日志输出为

    图片.png

    当执行startService()后执行bindService()方法,此时要销毁服务需要同时调用stopService()方法和unbindService()方法后,onDestory()方法才会被调用

    启动服务

    图片.png

    绑定服务

    图片.png

    停止服务和解除绑定服务

    图片.png

    Service的扩展知识

    使用前台服务

    前台服务的特征:有一个运行图标一直在系统的状态栏显示

        //服务被创建时调用
        @Override
        public void onCreate() {
            super.onCreate();
            Log.d(TAG, "onCreate");
            Intent intent=new Intent(this,MainActivity.class);
            /**
             * 第一个参数为上下文对象
             * 第二个参数为requestCode返回码
             * 第三个参数为Intent对象
             * 第四个参数为flags标识
             */
            PendingIntent pendingIntent=PendingIntent.getActivity(this,0,intent,0);
            Notification notification=new NotificationCompat.Builder(this)
                    .setContentTitle("This is content title")
                    .setContentText("This is content text")
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                            R.mipmap.ic_launcher))
                    .setContentIntent(pendingIntent)
                    .build();
            //启动前台服务,第一个参数为通知的id
            startForeground(1,notification);
        }
    
    GIF.gif

    服务的特征

    服务是运行在主线程中的,耗时操作会造成ANR
    在Service与Activity中分别加入以下代码打印线程id

            Log.d("MyService", "MainActivity thread id is " + Thread.currentThread().getId());
    
            Log.d("MyService", "Service thread id is " + Thread.currentThread().getId());
    
    图片.png

    由Log打印日志可知Service与Activity确实运行在同一线程中,因此不能在Service中进行耗时操作,正确的使用方法是在每个服务中去开启一个子线程,在子线程中进行耗时操作,写法可以为

        //服务被启动时调用
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.d(TAG, "onStartCommand");
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //在子线程中处理耗时操作
                    stopSelf();
                }
            }).start();
            return super.onStartCommand(intent, flags, startId);
        }
    

    开发中可能出现忘记开启线程或调用stopSelf()方法结束服务,所以可以使用IntentService类来创建一个异步且会自动停止的服务。
    IntentService类

    public class MyIntentService extends IntentService {
    
        //该无参构造方法必须实现,且格式固定,需要调用父类的有参构造函数来实例化Service
        public MyIntentService() {
            super("MyIntentService");
        }
    
        @Override
        protected void onHandleIntent(Intent intent) {
            //根据intent的不同来处理不同的逻辑
            Log.d("MyIntentService", "Thread id is " + Thread.currentThread().getId());
            String value = intent.getStringExtra("test");
            Log.d("MyIntentService", "intentService2 " + value);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.d("MyIntentService", "onDestroy");
        }
    }
    

    MainActivity

                case R.id.start_intent_service:
                    //启动IntentService服务
                    Log.d("MyIntentService", "Activity thread id is " + Thread.currentThread().getId());
                    Intent intentService = new Intent(this, MyIntentService.class);
                    Intent intentService2 = new Intent(this, MyIntentService.class);
                    intentService2.putExtra("test", "executed");
                    startService(intentService);
                    startService(intentService2);
                    break;
    
    图片.png

    由日志可以看出IntentService与Activity没有运行在同一线程中,且onHandleIntent()方法会先后处理不同的intent,只有处理完所有的intent请求后onDestory()方法才会执行,以此自动停止服务。

    相关文章

      网友评论

          本文标题:Android四大组件——Service

          本文链接:https://www.haomeiwen.com/subject/fyayextx.html