瞎忙到头晕...

Service主要使用在后台比较耗时和运行时间较长的逻辑。但是在service中使用 Thread.currentThread().getId() 获取得到的却是1,也就是主线程。如果想要在服务里执行耗时的逻辑,也需要创建一个子线程,否则也会阻塞线程。

左图是startService()所创建;右图是bindService()所创建。

目的就是让Activity指定Service去执行什么任务,这样一个简单操作。由于直接启动和关闭Service相信大家都会,在这就先不说了,无非就是调用了startService( )和stopService( ),参数是一个意图。

首先,先把AndroidManifest.xml中先将准备使用的Service注册上。

两个按钮,分别是开始绑定和解除绑定的按钮。

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="bind service"

android:onClick="bindService"/>

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="unbind service"

android:onClick="unbindService"/>

在Activity中把两个点击事件实现。这里我为了偷懒用了onClick,平时我还是用OnClickListener的。

public void bindService(View view)

public void unbindService(View view)

先在Service中实现一个继承自Binder的内部类,用来进行通讯。里面随便写一个方法,模拟做一些事情。

class MyBinder extends Binder {

public void download() {

Log.e(TAG, "start download ...");

这时候就要把onBind()这个方法中的返回值设置成刚才的内部类了。

private MyBinder mBinder = new MyBinder();

public IBinder onBind(Intent intent) {

return mBinder;

这样,Service中的修改基本就算结束了。接下来就是修改Activity了,在Activity中,主要就是创建了一个ServiceConnection这样一个类,并重写他它的两个方法onServiceConnected()和onServiceDisconnected(),值得注意的是,建立关联的时候:在onBind()方法中需返回一个IBinder实例,不然onServiceConnected方法不会调用;在解除关联的时候:onServiceDisconnected() 在连接正常关闭的情况下是不会被调用的, 该方法只在Service 被破坏了或者被杀死的时候调用。

经过向下转型,得到了MyBinder的实例,就可以随便调用MyBinder的任何方法了。

private BindService.MyBinder myBinder;

private ServiceConnection conn = new ServiceConnection() {

public void onServiceConnected(ComponentName componentName, IBinder iBinder) {

Log.e(TAG, "onServiceConnected()开始绑定");

myBinder = (BindService.MyBinder) iBinder;

myBinder.download();

public void onServiceDisconnected(ComponentName componentName) {

Log.e(TAG, "onServiceDisconnected()解除绑定");

最后,再把绑定和解除绑定的按钮添加完成。三个参数分别是意图;ServiceConnection;标志位。其中BINDAUTOCREATE表示在Activity和Service建立关联后自动创建Service。

public void bindService(View view) {

Log.e(TAG, "bindService()");

Intent bindIntent = new Intent(MainActivity.this, BindService.class);

bindService(bindIntent, conn, BIND_AUTO_CREATE);

public void unbindService(View view) {

Log.e(TAG, "unbindService()");

unbindService(conn);

这时候注意如果同时使用了startService()和bindService()方法来启动Service,这时候,只使用stopService()或者unbindService()方法都是关不掉的,解决方法就是把两个方法都用一遍:先使用stopService(),service还依然存在,再使用unbindService(),service就关闭了。

这一类Service是为了满足将数据的更新,且一直在前台显示的需求,类似于通知。事实上就是通知。:-)

同样,先起开一个Service。

public void startNotificationService(View view) {

Log.e(TAG, "startNotificationService()");

Intent startNotificationService = new Intent(MainActivity.this,NotificationService.class);

startService(startNotificationService);

并在AndroidManifest里注册这个Service。

接下来,就是通知栏的实现了,之前的那种setLatestEventInfo方式早已被弃用,所以我们直接用新的方式。

首先,我们先构建一个Notification,Notification的基本样式就在这里成型了。这里因为Service本身就是Context的一个实现,所以,我们直接传this就可以了。

Notification notification = new Notification.Builder(this)

.setContentTitle("This is Content Title")

.setContentText("This is Content Text")

.setSmallIcon(R.drawable.ic_launcher_foreground)

.setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.drawable.suyichen))

对应的:

然后,拿到NotificationManager。

NotificationManager notificationManager = (NotificationManager) this.getSystemService(this.NOTIFICATION_SERVICE);

最后,创建。第一个参数唯一的标识该Notification,第二个参数就是Notification对象。

notificationManager.notify(1, notification);

一个炒鸡简单的通知栏就实现了。

这不禁就要问了,远程Service和本地Service有什么区别呢?

远程嘛,顾名思义,就是说这个Service和调用者不存在一个进程中;相对的,本地Service和调用者是在一个进程中的。

那相对于本地Service,远程Service有什么优势吗?

远程Service可以常驻在后台,不受其他的Activity影响,可以说非常灵活。比如说,现在有一个非常非常耗时的操作需要执行,但是又不能把他放到本地Service中,因为本地Service其实是在主线程中运行的,这样的耗时操作会阻塞进程,造成ANR,这时候,远程Service就可以大展身手了。

使用场景当然是多个应用程序共享一个后台服务了。

好了,说了这么多,看一下具体实现吧,比如说我就是简单的获取一个字符串这样一个小功能。我这里全都写到了一个应用,在实际使用的时候大多是两个应用。

服务端:

首先需要建一个aidl文件,并定义他所需要的方法。

interface MyAIDL {

String getString();

这时候,一定要把studio重新build一下……,然后就在build - >generated ->source ->aidl->debug的目录下生成一个aidl文件。

紧接着,需要建一个Service,来提供一些远程服务。这里先将MyAIDL.Stub实现,然后重写里面的方法,最后onBind()方法中将MyAIDL.Stub的实现返回(Stub其实就是Binder的子类),主要的代码如下。

public IBinder onBind(Intent intent) {

return new MyBind();

class MyBind extends MyAIDL.Stub{

public String getString() throws RemoteException {

String string = "This is the string returned by the server";

return string;

客户端:

首先将刚刚在服务端创建的MyAIDL原封不动的复制到客户端来(路径要一模一样),剩下的与绑定本地服务差不多。

private MyAIDL myAIDL;

//connect remote service

private ServiceConnection remoteConn = new ServiceConnection() {

public void onServiceConnected(ComponentName name, IBinder service) {

myAIDL = MyAIDL.Stub.asInterface(service);

String str = myAIDL.getString();

Log.e(TAG,"return :" + str);

} catch (RemoteException e) {

e.printStackTrace();

public void onServiceDisconnected(ComponentName name) {

myAIDL = null;

剩下的,是开始绑定和解除绑定的地方了。

public void startRemoteService(View view) {

Log.e(TAG, "startRemoteService()");

Intent remoteServiceIntent = new Intent();

remoteServiceIntent.setAction("com.example.service.MyService");

remoteServiceIntent.setPackage("com.syc.service");

bindService(remoteServiceIntent,remoteConn,BIND_AUTO_CREATE);

public void stopRemoteService(View view) {

Log.e(TAG, "stopRemoteService()");

unbindService(remoteConn);

上面的setAction是服务端的AndroidManifest.xml;setPackage是设置Service所在服务端的包名。

android:name=".RemoteService"

android:process=":remote">

OK,这样,全部的远程Service就实现了。

Android对这类数据的格式支持只能传递Java的基本数据类型、字符串、List或Map等。如果想传递一个自定义的类就必须要让这个类去实现Parcelable接口,并且要给这个类也定义一个同名的AIDL文件去实现。

android studio四大组件,Android 四大组件 Service 完全理解相关推荐

  1. Android Studio 使用艺术 - Android Windows 开发环境配置

    为什么80%的码农都做不了架构师?>>>    Android Windows 开发环境配置 配置JDK 下载JDK8 下载地址:http://www.oracle.com/tech ...

  2. ❤️【Android精进之路-02】安装Android Studio,认识Android SDK,一步步学习❤️

    您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦. 本文会重点介绍Android SDK以及如何安装Android Studio进行Android开发. 干货满满,建议收藏,需要用到时常看看.小伙伴 ...

  3. Android Studio 第一次新建Android Gradle项目超级慢的解决方案

    Android Studio 第一次新建Android Gradle项目超级慢的解决方案 参考文章: (1)Android Studio 第一次新建Android Gradle项目超级慢的解决方案 ( ...

  4. 在Android Studio中打开Android Device Monitor时报错的解决方法

    在Android Studio中打开Android Device Monitor时报错的解决方法 参考文章: (1)在Android Studio中打开Android Device Monitor时报 ...

  5. android studio撤销按钮,Android Studio无法撤消(Android Studio Can't Undo)

    Android Studio无法撤消(Android Studio Can't Undo) 有时候当我尝试撤销Android Studio中的更改时,我得到以下结果: 无法撤消 受此操作影响的文件已被 ...

  6. mac 下启动Android Studio 时出现 Android Studio was unable to find a valid Jvm

    如题:mac 下启动Android Studio 时出现 Android Studio was unable to find a valid Jvm 解决方法如下: Before you set up ...

  7. arcore_如何使用ARCore和Android Studio构建增强现实Android应用

    arcore by Ayusch Jain 通过Ayusch Jain 如何使用ARCore和Android Studio构建增强现实Android应用 (How to build an Augmen ...

  8. android studio云测,Android studio 下的robotium自动化测试和持续集成

    [背景介绍] Android Studio 是一个Android开发环境,基于IntelliJ IDEA. 类似 Eclipse ADT,Android Studio 提供了集成的 Android 开 ...

  9. android studio(1)---探索Android Studio

    探索 Android Studio Android Studio 是基于 IntelliJ IDEA 的官方 Android 应用开发集成开发环境 (IDE). 除了 IntelliJ 强大的代码编辑 ...

  10. 【android studio】解决android studio drawable新建项目时只有一个drawable目录的问题

    [android studio]解决android studio drawable新建项目时只有一个drawable目录的问题 参考文章: (1)[android studio]解决android s ...

最新文章

  1. 优秀好文收录(持续更新...)
  2. Android:阻止输入法将图片压缩变形
  3. SDNU 1474.特殊回文数(水题)
  4. 入门干货:Python操作Word文件经验分享
  5. 2.VMware View 4.6安装与部署-域环境
  6. Servlet线程安全性
  7. 人体静止存在雷达探测,雷达感应模组技术,物联网智能化发展
  8. 还在用Excel做报表?建议你试试这个数据填报系统_光点科技
  9. 逾 200 家港企参与! GoGBA大湾区发展日(广州)圆满举行
  10. idea 右侧的maven没有dependencies
  11. java rar_java如何解压rar文件
  12. android.view.ContextThemeWrapper cannot be cast to android.app.Activity
  13. 【传智播客郑州校区分享】AndroidAnnotations框架详解
  14. Linux克隆虚拟机
  15. FHS 文件系统的理解
  16. centos6.5kvm虚拟化技术
  17. 你了解多线程自旋锁、互斥锁、递归锁等锁吗?
  18. 如何正确地进入基于x86-64Bit Windows系统的商业软件破解领域
  19. LocalDate与Date相互转换
  20. Java修炼之凡界篇 筑基期 第03卷 流程控制 第03话 选择结构

热门文章

  1. mysql 主从复制讲解_mysql主从复制 详解
  2. 【算法导论】三门问题-蒙提霍尔问题
  3. Spring @Autowire 源码分析
  4. 15 个 Java 线程面试题和答案
  5. 算法--冒泡排序原理
  6. qduoj LC的课后辅导(单调栈)
  7. 前端框架OnsenUI学习之ons-navigator介绍
  8. 计算机主板上包含总线,计算机三级(PC技术)笔试106.doc
  9. Android 驱动和系统开发 2. 解析模拟器GPS模块
  10. Excel 2010 SQL应用032 字符范围的模糊匹配查询