Service

生命周期

image

1、简介

服务存在两种,
一种事本地服务Local Service,本地服务用于应用程序内部
一种是远程服务Remote Service,用于android 系统内部的应用程序之间

2、本地服务

本地服务通常有两种启动方式: start 启动方式  和 bind启动方式

a、start启动方式

1,onCreate() 创建服务,多次创建方法只运行一次
2,onStartCommand() start一次执行一次
3,onDestroy() 外部调用了stopService或者stopSelf 时执行

  • Service代码

    /**
     * start启动
     */
    
    public class LocalService extends Service {
    
      @Override
      public void onCreate() {
          Log.i("Kathy", "onCreate - Thread ID = " + Thread.currentThread().getId());
          super.onCreate();
      }
    
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
          Log.i("Kathy", "onStartCommand - startId = " + startId + ", Thread ID = " + Thread.currentThread().getId());
          return super.onStartCommand(intent, flags, startId);
      }
    
      @Nullable
      @Override
      public IBinder onBind(Intent intent) {
          Log.i("Kathy", "onBind - Thread ID = " + Thread.currentThread().getId());
          return null;
      }
    
      @Override
      public void onDestroy() {
          Log.i("Kathy", "onDestroy - Thread ID = " + Thread.currentThread().getId());
          super.onDestroy();
      }
    }
    
  • AndroidManifest代码

    <!--本地服务-->
    <service android:name=".local.LocalService" />
    
  • Activity代码

    //start启动方式
    Intent service = new Intent(this, LocalService.class);
    startService(service);
    

b,bind启动方式

1,bindService启动的服务和调用者是 client-service 模式,一个service 可以被多个client绑定,
2,同一个界面绑定多次,onCreate、onStartCommand只会执行一次,bind方法可以执行多次
3,当client被销毁时自动与Service解除绑定,client也可以调用unbindService与Service解除绑定,
4,当时Service没有任何client与Service绑定的时候,自动会被销毁

  • Service代码

    /**
       * bind服务
    */
    
    public class LocalBindService extends Service {
    
      //client 可以通过Binder 获取Service
      public class LocalBinder extends Binder {
          public LocalBindService getService() {
              return LocalBindService.this;
          }
      }
    
      //Client与Service 之间通讯
      private LocalBinder localBinder = new LocalBinder();
      private final Random random = new Random();
    
      @Override
      public void onCreate() {
          Log.i("Kathy", "LocalBindService - onCreate - Thread = " + Thread.currentThread().getName());
          super.onCreate();
      }
    
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
          Log.i("Kathy", "LocalBindService - onStartCommand - startId = " + startId + ", Thread = " + Thread.currentThread().getName());
          return super.onStartCommand(intent, flags, startId);
      }
    
    
      @Nullable
      @Override
      public IBinder onBind(Intent intent) {
          Log.i("Kathy", "LocalBindService - onBind - Thread = " + Thread.currentThread().getName());
          return localBinder;
      }
    
    
      @Override
      public boolean onUnbind(Intent intent) {
          Log.i("Kathy", "LocalBindService - onUnbind - from = " + intent.getStringExtra("from"));
          return super.onUnbind(intent);
      }
    
      @Override
      public void onDestroy() {
          Log.i("Kathy", "LocalBindService - onDestroy - Thread = " + Thread.currentThread().getName());
          super.onDestroy();
      }
    
      //getRandomNumber是Service暴露出去供client调用的公共方法
      public int getRandomNumber() {
          return random.nextInt();
      }
    }
    
  • Activity代码

    /**
       * 绑定界面
    */
    
    public class BindServiceActivity extends AppCompatActivity {
    
      private LocalBindService localBindService;
      private boolean isBind = false;
    
      private ServiceConnection serviceConnection = new ServiceConnection() {
          @Override
          public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
              isBind = true;
              LocalBindService.LocalBinder localBinder = (LocalBindService.LocalBinder) iBinder;
              localBindService = localBinder.getService();
              Log.i("Kathy", "BindServiceActivity - onServiceConnected");
              int num = localBindService.getRandomNumber();
              Log.i("Kathy", "BindServiceActivity - getRandomNumber = " + num);
          }
    
          @Override
          public void onServiceDisconnected(ComponentName componentName) {
              isBind = false;
              Log.i("Kathy", "BindServiceActivity - onServiceDisconnected");
          }
      };
    
      @Override
      public void onCreate(@Nullable Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.bind_service_main);
    
      }
    
      //绑定服务
      public void bind(View view) {
          Intent bindService = new Intent(this, LocalBindService.class);
          Log.i("Kathy", "BindServiceActivity - bind");
          bindService(bindService, serviceConnection, BIND_AUTO_CREATE);
      }
    
      //解除绑定
      public void unbind(View view) {
          Log.i("Kathy", "BindServiceActivity - unbind");
          unbindService(serviceConnection);
      }
    
      //下一个页面
      public void next(View view) {
          Intent intent = new Intent(this, BindServiceActivity.class);
          startActivity(intent);
          finish();
      }
    
      @Override
      protected void onDestroy() {
          super.onDestroy();
          Log.i("Kathy", "BindServiceActivity - onDestroy");
      }
    }
    

2、远程服务

远程服务也被称为独立进程,它可以用于两种情况
1,同一个app中运行
2,不同app中运行

a,AIDL接口的创建

远程服务需要通过AIDL定义的接口提供给client

注:如果服务端与客户端不在同一App上,需要在客户端、服务端两侧都建立该aidl文件。

Android Studio 中的新建栏目里面存在一个可以直接创建的选择


image.png
  • IMyAidlInterface代码

    // IMyAidlInterface.aidl
    package poetry.com.service.remote;
    
    // Declare any non-default types here with import statements
    
    interface IMyAidlInterface {
        /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
        String getValue();
    }
    

b,Service的创建

/**
 * 远程服务
 */

public class RemoteService extends Service {

    private final Random random = new Random();

    //实现接口中暴露给客户端的stub
    private IMyAidlInterface.Stub stub = new IMyAidlInterface.Stub() {
        @Override
        public String getValue() throws RemoteException {
            return getRandomNumber();
        }
    };

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

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


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


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

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

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

c,AndroidMainfest配置

<!--远程服务-->
    <service
        android:name=".remote.RemoteService"
        android:process="com.remote">
        <intent-filter>
            <action android:name="poetry.com.service.remote.RemoteService" />
        </intent-filter>
    </service>

注意:
andorid:process属性设置
1,私有进程以冒号‘:’为前缀,这表示新的进程名为yourPackage:remote,其他应用的组件不可以和它运行在同一进程中
2,全局进程不以冒号‘:’为前缀,以小写字母开头,表示其他应用可以通过设置相同的ShareUID和它运行在同一个进程中

d,Activity的使用

/**
 * 远程服务界面
 */

public class RemoteServiceActivity extends AppCompatActivity {

    private IMyAidlInterface iMyAidlInterface;


    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);

            Log.i("Kathy", "RemoteServiceActivity - onServiceConnected");
            String num = null;
            try {
                num = iMyAidlInterface.getValue();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
             Log.i("Kathy", "RemoteServiceActivity - getRandomNumber = " + num);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.i("Kathy", "RemoteServiceActivity - onServiceDisconnected");
            // 断开连接
            iMyAidlInterface = null;
        }
    };


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.bind_service_main);

    }

    //绑定服务
   public void bind(View view) {
        Intent bindService = new Intent(this, RemoteService.class);
        Log.i("Kathy", "RemoteServiceActivity - bind");
        bindService(bindService, serviceConnection, BIND_AUTO_CREATE);
    }

    //解除绑定
    public void unbind(View view) {
        Log.i("Kathy", "RemoteServiceActivity - unbind");
        unbindService(serviceConnection);
    }

    //下一个页面
    public void next(View view) {
        Intent intent = new Intent(this, RemoteSecondeActivity.class);
        startActivity(intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("Kathy", "RemoteServiceActivity - onDestroy");
        if (serviceConnection != null) {
            unbindService(serviceConnection);
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容

  • 本篇文章是继续上篇android图片压缩上传系列-基础篇文章的续篇。主要目的是:通过Service来执行图片压缩任...
    laogui阅读 4,441评论 5 62
  • 前言:本文所写的是博主的个人见解,如有错误或者不恰当之处,欢迎私信博主,加以改正!原文链接,demo链接 Serv...
    PassersHowe阅读 1,413评论 0 5
  • Service是Android四大组件之一,主要用于执行需要长时间运行的任务或者处理一些耗时的逻辑。Serv...
    Kyunban阅读 545评论 0 0
  • 还是那熟悉的身影, 那个听了以后, 就觉得就算全世界都背叛了我, 都无所谓的踏实。 刘瑞丽, 从今天起,做最好的自...
    玫瑰花的梦阅读 227评论 0 1
  • 文/简书小二 - 我身边有好多出入社会工作的朋友每逢年底大家谈起工作或是交流有没有存点儿钱的时候,他们都说没有,我...
    简书小二阅读 720评论 3 10