Android四大组件Service

网友投稿 690 2022-05-30

作用:

是在后台长期运行某些服务,如复杂的计算 、音乐播放、下载等等。

分类:

Service按运行的位置划分有:本地服务、远程服务

Service按运行的类型划分有:前台服务、后台服务

Service按运行的功能划分有:可通信服务、不可通信服务

下面逐一讲解。

本地服务与远程服务

本地服务使用步骤

本地服务使用步骤1: 新建子类继承Service类,重写父类的onCreate()、onStartCommand()、onDestroy()和onBind()方法。

package com.ti.myservice; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; // 本地Service这是最常用的 public class LocalService extends Service { public LocalService() { } @Override public void onCreate() { super.onCreate(); Log.d("本地Service#","onCreate创建服务"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("本地Service#","onStartCommand开始服务"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d("本地Service#","onDestroy销毁服务"); } @Override public IBinder onBind(Intent intent) { Log.d("本地Service#","onBind绑定服务"); return null; } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

本地服务使用步骤2: 在AndroidManifest.xml里注册Service

... ...

1

2

3

4

5

6

7

8

9

10

11

12

AndroidManifest.xml里Service标签的常见属性:

本地服务使用步骤3: 构建用于启动Service的Intent对象

启动Service Intent

Intent startLocalServiceIntent = new Intent(MainActivity.this,LocalService.class);

1

终止Service Intent

Intent stopLocalServiceIntent = new Intent(MainActivity.this,LocalService.class);

1

本地服务使用步骤4:

调用startService()启动Service

Intent startLocalServiceIntent = new Intent(MainActivity.this,LocalService.class); startService(startLocalServiceIntent);

1

2

调用stopService()停止服务

Intent stopLocalServiceIntent = new Intent(MainActivity.this,LocalService.class); stopService(stopLocalServiceIntent);

1

2

本地服务运行结果:

2019-07-22 18:27:59.377 17266-17266/com.ti.myservice D/本地Service#: onCreate创建服务 2019-07-22 18:27:59.378 17266-17266/com.ti.myservice D/本地Service#: onStartCommand开始服务 2019-07-22 18:28:09.813 17266-17266/com.ti.myservice D/本地Service#: onDestroy销毁服务

1

2

3

远程服务使用

远程服务(Remote Service)也被称之为独立进程,它不受其它进程影响,可以为其它应用程序提供调用的接口——实际上就是进程间通信IPC(Inter-Process Communication),Android提供了AIDL(Android Interface Definition Language,接口描述语言)工具来帮助进程间接口的建立。

在Android中,不同的应用属于不同的进程(Process),一个进程不能访问其它进程的存储,但是可以通过ContentProvider实现,如:通讯录的读取。

远程服务与本地服务最大的区别是:远程Service与调用者不在同一个进程里(即远程Service是运行在另外一个进程);而本地服务则是与调用者运行在同一个进程里。

将一个Service变成远程服务,加上android:process=":remote"就可以了,然后它就在另一个进程里自己运行了,你要和它通信就要用AIDL的方式了。

... ...

1

2

3

4

5

6

7

8

9

10

11

12

13

14

远程服务的讲解,独立成一章《远程服务Service & AIDL & IPC》

前台服务与后台服务

前台服务使用步骤

创建前台服务步骤1:

编写继承Service的子类,重写onCreate()方法,在其中开启前台线程。这样既可以使用startService(),也可以使用bindService()开启前台服务,因为它们都会执行onCreate方法。

如果把开启前台线程写到onStartCommand(),那么只能用startService()开启前台服务,bindService()就开启不了,因为用bindService开启,onStartCommand不会被执行。

如果把开启前台线程写到onBind,那么只能用用bindService开启,因为startService调用时,onBind不会被执行。而只有onCreate是两种开启方法时都会被调用的。

@Override public void onCreate() { super.onCreate(); String id = "channel_01"; String name="我是渠道名字"; // 添加下列代码将后台Service变成前台Service // 构建点击通知后打开MainActivity的Intent对象 Intent notificationIntent = new Intent(this,MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT); //获取系统通知服务 NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); Notification notification = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel mChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_LOW); notificationManager.createNotificationChannel(mChannel); notification = new Notification.Builder(this,id) .setContentTitle("前台服务通知的标题")// 设置通知的标题 .setContentText("前台服务通知的内容")// 设置通知的内容 .setSmallIcon(R.mipmap.ic_launcher)// 设置通知的图标 .setContentIntent(pendingIntent)// 设置点击通知后的操作 .build(); } else { notification = new NotificationCompat.Builder(this) .setContentTitle("前台服务通知的标题") .setContentText("前台服务通知的内容") .setSmallIcon(R.mipmap.ic_launcher) .setOngoing(true) .setChannelId(id) .setContentIntent(pendingIntent) //设置pendingIntent,点击通知时就会用到 .build(); } startForeground(1, notification);// 让Service变成前台Service,并在系统的状态栏显示出来 Log.d("前台Service#","onCreate创建服务"); }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

创建前台服务步骤2:

在AndroidManifest.xml中注册服务。

... ... ...

1

2

3

4

5

6

7

8

9

10

11

12

13

14

创建前台服务步骤3:开启服务。

用startService开启

Intent startFrontServiceIntent = new Intent(MainActivity.this,FrontService.class); startService(startFrontServiceIntent);

1

2

关闭

Intent stopFrontServiceIntent = new Intent(MainActivity.this,FrontService.class); stopService(stopFrontServiceIntent);

1

2

用bindService绑定服务:

private ServiceConnection testServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { } @Override public void onServiceDisconnected(ComponentName name) { } }; bindService(startFrontServiceIntent,testServiceConnection,BIND_AUTO_CREATE);

1

2

3

4

5

6

7

8

9

解绑:

unbindService(testServiceConnection);

1

可通信服务与不可通信服务

可通信服务使用步骤

可通信服务使用步骤1: 新建子类继承Service类和定义一个Binder。

package com.ti.myapplication; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class CommunicationService extends Service { private CommunicationBinder mBinder = new CommunicationBinder("可通信Service"); public CommunicationService() { } @Override public void onCreate() { super.onCreate(); Log.d("可通信Service#","onCreate创建服务"); } // 可通信Service在绑定服务时,不会执行onStartCommand方法 @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("可通信Service#","onStartCommand开始服务"); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { Log.d("可通信Service#","onBind绑定服务"); return mBinder; } @Override public boolean onUnbind(Intent intent) { Log.d("可通信Service#","onUnbind解绑服务"); return super.onUnbind(intent); } @Override public void onDestroy() { super.onDestroy(); Log.d("可通信Service#","onDestroy销毁服务"); } //新建一个子类继承自Binder类 class CommunicationBinder extends Binder { private String name; public CommunicationBinder(String name){ this.name = name; } public void service_connect_Activity() { Log.d("","Service关联了Activity,并在Activity执行了Service的方法"); } public String getName() { return name; } public void setName(String name) { this.name = name; } } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

Android四大组件之Service

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

可通信服务使用步骤2: 在AndroidManifest.xml中注册服务

... ...

1

2

3

4

5

6

7

8

9

10

11

12

13

可通信服务使用步骤3: 准备好ServiceConnection

private CommunicationService.CommunicationBinder myBinder; // 创建ServiceConnection的匿名类 private ServiceConnection connection = new ServiceConnection() { // 重写onServiceConnected()方法和onServiceDisconnected()方法 // 在Activity与Service建立关联和解除关联的时候调用 @Override public void onServiceDisconnected(ComponentName name) { } //在Activity与Service解除关联的时候调用 @Override public void onServiceConnected(ComponentName name, IBinder service) { // 实例化Service的内部类myBinder // 通过向下转型得到了MyBinder的实例 myBinder = (CommunicationService.CommunicationBinder) service; // 在Activity调用Service类的方法 myBinder.service_connect_Activity(); } };

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

可通信服务使用步骤4: 绑定服务

package com.ti.myapplication; 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.view.View; public class MainActivity extends AppCompatActivity { private CommunicationService.CommunicationBinder myBinder; // 创建ServiceConnection的匿名类 private ServiceConnection connection = new ServiceConnection() { // 重写onServiceConnected()方法和onServiceDisconnected()方法 // 在Activity与Service建立关联和解除关联的时候调用 @Override public void onServiceDisconnected(ComponentName name) { } //在Activity与Service解除关联的时候调用 @Override public void onServiceConnected(ComponentName name, IBinder service) { // 实例化Service的内部类myBinder // 通过向下转型得到了MyBinder的实例 myBinder = (CommunicationService.CommunicationBinder) service; // 在Activity调用Service类的方法 myBinder.service_connect_Activity(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.bind_service).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 构建绑定服务的Intent对象 Intent bindServiceIntent = new Intent(MainActivity.this,CommunicationService.class); // 第一个参数:Intent对象 // 第二个参数:上面创建的ServiceConnection实例 // 第三个参数:标志位 // 这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service // 这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行 bindService(bindServiceIntent,connection,BIND_AUTO_CREATE); } }); findViewById(R.id.unbind_service).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 调用unbindService()解绑服务 // 参数是上面创建的Serviceconnection实例 unbindService(connection); } }); } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

测试结果:

2019-07-22 20:09:59.662 17540-17540/com.ti.myapplication D/可通信Service#: onCreate创建服务 2019-07-22 20:09:59.663 17540-17540/com.ti.myapplication D/可通信Service#: onBind绑定服务 2019-07-22 20:10:01.067 17540-17540/com.ti.myapplication D/可通信Service#: onUnbind解绑服务 2019-07-22 20:10:01.068 17540-17540/com.ti.myapplication D/可通信Service#: onDestroy销毁服务

1

2

3

4

Service与Thread

它们没有任何的关系,但它们常常在一起组合着使用。

Service与Thread的相同点:都是用于执行异步操作的。

Service与Thread的不同点:

Service运行在主线程,Thread运行在工作线程

Servcie运行在主线程,不依赖UI/Activity,Thread则要依赖在某个Activity上。

Service的生命周期

远程服务的讲解,独立成一章《远程服务Service & AIDL & IPC》

关于本地服务、可通信服务、前台服务的使用的demo已上传Github。欢迎下载学习!

Android 任务调度 网站

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:分布式文件系统如何做?终于有篇文章分布式文件上传讲清楚了
下一篇:DDD领域驱动设计实战-聚合(Aggregate)和聚合根(AggregateRoot)
相关文章