美文网首页
(二)Service

(二)Service

作者: lanfairy | 来源:发表于2019-08-27 13:44 被阅读0次

    什么是Service
    Service是一个长期运行在后台没有用户界面的Android组件。

    在Android中后台是相对UI前台而言的,后台不是子线程。
    ServiceThread没有任何关系
    Service是运行在主线程中的,若直接在Service里面做耗时操作很容易造成ANR「Application Not Responding」,故在Service中不能直接做耗时操作,要想做耗时操作只能在Service中创建的子线程中进行。

    • Android中有两种Service
      1. Service
    //AndroidManifest文件中注册service
     <service android:name=".test.MyService" />
    
      1.1 Service 是单向的  不受控的
    
    @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            Intent intent = new Intent(MainActivity.this, MyService.class);
            //启动Service
            startService(intent);
        }
    
    //这个Service 是单向的  不受控的
    // Context.startService(...)之后,Service的 onCreate()和onStartCommand(...)会得到执行。
    //之后Service会一直处于运行状态,但具体运行的是什么逻辑,Context就控制不了了。
    // 这就好比Activity通知了服务一下:『喂,哥们你可以干活去了』,然后服务就去忙自己的事情了,
    // 但Activity并不知道Service到底去做什么了,以及完成的如何。
    // Service去干活怎么干不受Context控制,
    // Service与Context没任何交流
    public class MyService extends Service {
       @Override
       public IBinder onBind(Intent intent) {
           return null;
       }
    //会在Service第一次创建时调用
    // 若多次调用Context.startService(...)  此方法只会执行一次
       @Override
       public void onCreate() {
           super.onCreate();
       }
    //每次启动Service时调用
       @Override
       public int onStartCommand(Intent intent, int flags, int startId) {
           //new MyAsyncTask().execute();
           //创建并开启子线程进行耗时任务
           new Thread(new Runnable() {
               @Override
               public void run() {
                   //耗时操作。。。
                   Log.i("创建并开启子线程进行耗时任务", "run");
                   //耗时操作处理完毕后  不一定要停掉Service 否则会造成内存泄漏
                   stopSelf();
               }
           }).start();
           return super.onStartCommand(intent, flags, startId);
       }
    //会在Service销毁时调用
       @Override
       public void onDestroy() {
           super.onDestroy();
       }
    }
    
    public class MyAsyncTask extends AsyncTask<Void, Integer, Boolean> {
    
        //在后台任务开始执行之前调用,用于进行一些界面上的初始化操作。(初始化工作)
        @Override
        protected void onPreExecute() {
            //显示进度对话框。。。
            super.onPreExecute();
        }
    
        /**
         * 这个方法中的代码都会在子线程中运行,在这里处理所有的耗时操作任务。
         * 这个方法中不可进行UI操作,可调用publishProgress(Progress...)来完成UI更新。
         * retun 返回任务的执行结果
         */
        @Override
        protected Boolean doInBackground(Void... voids) {
            //耗时操作
            return true;
        }
    
        /**
         * 调用publishProgress(...)方法后,onProgressUpdate这个方法就被调用,在这个方法中可以对UI进行操作
         */
        @Override
        protected void onProgressUpdate(Integer... values) {
            //更新UI   如进度条。。。
            super.onProgressUpdate(values);
        }
    
        /**
         * 当后台线程任务执行完毕并通过return进行返回时,
         * 这个方法就会被调用。在这个方法中根据传参(任务执行的结果)
         * 进行相应的UI及逻辑操作。
         */
        @Override
        protected void onPostExecute(Boolean aBoolean) {
            //关闭进度对话框  。。。
    //此处 停止service
            super.onPostExecute(aBoolean);
        }
    }
    
    1.2  Service 是双向的  可控的
    
    public class MyService2 extends Service {
        private static final String TAG = "MyService2";
        //Context通过Binder对Service进行控制
        private DownloadBinder downloadBinder = new DownloadBinder();
    
        @Override
        public IBinder onBind(Intent intent) {
            return downloadBinder;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
        }
    
        class DownloadBinder extends Binder {
            public void startDownload() {
                Log.i(TAG, "startDownload...");
            }
    
            public int getProgress() {
                Log.i(TAG, "getProgress...");
                return 0;
    
            }
        }
    }
    
    
    //MainActivity中
      private MyService2.DownloadBinder downloadBinder;
        private ServiceConnection serviceConnection;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            serviceConnection = new ServiceConnection() {
                @Override
                public void onServiceConnected(ComponentName name, IBinder service) {
                    downloadBinder = (MyService2.DownloadBinder) service;
                    downloadBinder.startDownload();
                    downloadBinder.getProgress();
                }
    
                @Override
                public void onServiceDisconnected(ComponentName name) {
                    downloadBinder.stopDownload();
                }
            };
            Intent intent = new Intent(MainActivity.this, MyService2.class);
            //绑定Service   BIND_AUTO_CREATE ---> 绑定之后自动创建Service
            bindService(intent, serviceConnection, BIND_AUTO_CREATE);
            
            //解绑
            unbindService(serviceConnection);
        }
    

    注意: 若同时调用了bindService(intent, serviceConnection, BIND_AUTO_CREATE)和startService(intent),相应就要同时stopService(intent)和unbindService(serviceConnection)

    1. IntentService(增强版的Service,集开启线程,以及任务完成后停止service于一身)
    //用法和普通的Service一样   startService(...) 或 bindService(...)
    public class MyIntentService extends IntentService {
        public MyIntentService() {
            super("MyIntentService");
        }
    
        //这个方法已经在子线程,无需担心ANR
        //Serive任务完成后会自动停止服务
        @Override
        protected void onHandleIntent(Intent intent) {
            //耗时操作
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
        }
    
    
        @Override
        public IBinder onBind(Intent intent) {
            return super.onBind(intent);
        }
    }
    
    

    使用场景

    1. 前台保活

      • 使用服务的原因:普通服务(后台服务)的优先级低,系统出现内存不足时,很容易回收掉正在后台运行的服务。「比如后台运行播放音乐,用着用着音乐服务没了」。若想让服务一直保持运行状态,而不会由于系统内存不中的原因导致被回收,就可以考虑使用前台服务。
    2. 普通服务与前台服务的区别

      • 一直有一个正在运行的图标在系统的状态栏显示,下拉状态栏可以看到更加详细的信息,类似于通知的效果。
    //只需要修改一下MyService类中的onCreate方法
    @Override
      public void onCreate() {
          super.onCreate();
          Intent intent = new Intent(this, MainActivity.class);
          PendingIntent pi = 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(pi)
                  .build();
          startForeground(1, notification);
    
      }
    

    原理

    参考:
    https://developer.android.google.cn/guide/components/services#Foreground

    相关文章

      网友评论

          本文标题:(二)Service

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