Service的理解

转自 原文

Service的理解

Service是什么?
Service是一种可以在后台运行相关任务的组件。没有界面。其存在的线程是主线程,一般会通过启动子线程来执行耗时操作。
Service有什么用?
可用于在后台执行下载任务。从而不影响用户界面操作。
Service分启动型服务、绑定型服务两种。
绑定服务中的创建Binder的扩展类的目的是什么?
该类主要用于获取Service的实例,以及执行相关的方法。
额外知识
1.不绑定服务,直接点击取消绑定服务会报错。因此需要通过判断Binder对象是否为空来处理。
2.服务可以不定义Action,通过Intent指定要跳转的Service即可。
3.Service的有效范围是所有满足条件的Activity。
4.在Service里执行耗时操作会导致ANR,启动新的线程执行耗时操作可有效避免。

两种服务的区别

Service类型 说明 使用步骤
启动型服务 1.生命周期为onCreate->onStartCommand->onDestroy 
2.服务一旦启动后,需要调用stopService方法或stopSelf方法才能停止。 
3.可常驻系统。
1.通过调用startService启动服务 
2.通过stopService停止服务
绑定型服务 1.生命周期为onCreate->onBind->onUnbind->onDestory 
2.需要返回Binder对象,即定义Binder的子类。
3.通过Binder子类的方法来获取Service对象,用于与Activity交互。 
4.在Activity中需要通过创建ServiceConnection对象来获取service实例。从而调用service里的方法。
1.通过bindService绑定服务 
2.通过unbindService取消绑定服务

Service生命周期

Service的类型及其示例

启动型服务 - StartService

使用
1.创建java类继承Service
2.重写onStart、onCreate等方法。
3.在onCreate中新开子线程,用于执行任务。

示例 - 启动型服务

Service作用
打印0-2000的数字,完毕后停止服务

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
public class CalcService extends Service {    private int total;    private boolean openService; //结束服务时的标识

public CalcService() {    }

@Override    public IBinder onBind(Intent intent) {        // TODO: Return the communication channel to the service.        throw new UnsupportedOperationException("Not yet implemented");    }

@Override    public void onCreate() {        super.onCreate();        LogTool.e("CalcService", "onCreate");    }

@Override    public int onStartCommand(final Intent intent, int flags, final int startId) {

LogTool.e("CalcService", "onStartCommand");        Functions.toast("Service已启动,请查看LOG");        //启动线程执行耗时操作。通常是下载之类的任务        new Thread(new Runnable() {            @Override            public void run() {                while (!openService) {                    try {                        Thread.sleep(100);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    LogTool.e("CalcService", total);                    total++;                    builder.setSubText("total:" + total);                    if (total == 2000) {                        stopSelf();                    }                }            }        }).start();        return super.onStartCommand(intent, flags, startId);    }

@Override    public void onDestroy() {        super.onDestroy();        LogTool.e("CalcService", "onDestroy");        Functions.toast("CalcService已停止,请查看LOG");        openService = true;    }}
12345
// Activity中的代码public void startService(View v){  Intent intent = new Intent(this,CalcService.class);  startService(intent);}

绑定型服务 - BindService

BindService(Intent,ServiceConnection,Context.BIND_AUTO_CREATE)
参数分别为Intent,ServiceConnection,标识号。通常为BIND_AUTO_CREATE。
使用
1.创建java类继承Service
2.创建Java类继承Binder类。用于返回Service实例。
3.重写onBind、onUnBind等方法。
4.在Activity中创建ServiceConnection对象,并获取Binder实例。
ps:为防止未绑定服务,用户点击取消绑定而导致的崩溃。需要对unbindService进行边缘性处理。

示例 - 普通绑定型服务

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
public class BindService extends Service {    private BindService service;    private TestBinder binder = new TestBinder();    private int count = 0;

public class TestBinder extends Binder {        //通过Binder对象来获取服务对象,从而调用服务里的方法        public BindService getService() {            if (service == null) {                service = new BindService();            }            return service;        }    }

private boolean closeThread;

public BindService() {    }

@Override    public void onCreate() {        super.onCreate();        new Thread(new Runnable() {            @Override            public void run() {                while (!closeThread) {                    LogTool.e("BindService", "count:" + count);                    count++;                }            }        }).start();    }

@Override    public TestBinder onBind(Intent intent) {        LogTool.e("BindService", "onBind");        return binder;    }

@Override    public void onDestroy() {        super.onDestroy();        this.closeThread = true;        LogTool.e("BindService", "onDestroy");        Functions.toast("BindService已停止");    }

@Override    public boolean onUnbind(Intent intent) {        LogTool.e("BindService", "onUnbind");        return true;    }

public void startDownload() {        Functions.toast("开始执行耗时任务,点击UnbindService按钮或返回按钮可取消任务");    }

}

Activity中的代码

1234567891011121314151617181920212223242526
private ServiceConnection connection = new ServiceConnection() {    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        binder = (BindService.TestBinder) service;        binder.getService().startDownload();    }

@Override    public void onServiceDisconnected(ComponentName name) {        Functions.toast("断开连接");        LogTool.e("BindService", "serviceDisconnected");    }};

//启动服务public void BindService(View v) {    Intent intent = new Intent(this, BindService.class);    bindService(intent, connection, Service.BIND_AUTO_CREATE);}

// 取消绑定服务,边缘性处理public void UnbindService(View v) {    if (binder != null) {        unbindService(connection);    }}

示例 - 绑定型远程服务

理解
如何定义远程服务?
在配置文件中添加代码android:progress=”:remote”即可
为什么设置了Service为远程Service就不会导致ANR了?
远程服务是指将服务放到另一个进程中执行,所以就不会导致程序的ANR现象。
如何跨进程与Activity进行通信? 见示例
如何实现跨程序通信?

示例 - 实现跨进程与Activity交互

步骤
1.创建aidl文件,定义接口(TestInterface)及相关方法。点击make project,自动生成Stub相关的接口。
2.创建Service类,并在ManiFest文件设置远程属性。android:process=”:remote”
3.在Service中创建接口TestInterface.Stub 对象,重写接口方法。
4.在Activity中通过AIDL接口的asInterface方法来获取AIDL对象。
5.利用接口对象调用相关方法。

12345
// 创建aidl文件,定义接口。package io.tanjundang.study.test.service;interface RemoteAidlInterface {  void calcMsg();}
1234
// 配置服务远程属性<service        android:name=".test.service.RemoteService"        android:process=":remote" />
12345678910111213141516
// Service中创建远程接口的Stub对象public class RemoteService extends Service {

RemoteAidlInterface.Stub mBinder = new RemoteAidlInterface.Stub() {        @Override        public void calcMsg() throws RemoteException {            LogTool.e("RemoteService", "66666");        }    };

@Override    public Binder onBind(Intent intent) {        return mBinder;    }

}
1234567891011121314151617181920212223242526272829303132333435363738
// Activity中调用远程接口的方法public class RemoteActivity extends AppCompatActivity {

private RemoteAidlInterface mBinder;    private ServiceConnection connection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {            mBinder = RemoteAidlInterface.Stub.asInterface(iBinder);            try {                mBinder.calcMsg();            } catch (RemoteException e) {                e.printStackTrace();            }        }

@Override        public void onServiceDisconnected(ComponentName componentName) {

}    };

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_remote);    }

public void StartRemoteService(View v) {        Intent intent = new Intent(this, RemoteService.class);        bindService(intent, connection, BIND_AUTO_CREATE);    }

public void UnbindRemoteService(View v) {        if (mBinder != null) {            unbindService(connection);        }    }}

示例 - 实现跨程序与Activity交互

步骤
实现步骤跟上面类似。只是需要为Service定义Action,以及将AIDL接口及其包名复制到另一程序中。即可实现跨程序交互。

IntentService

理解
为什么有这个类?
该类是Service的子类,主要是简化了异步操作繁琐复杂的代码。
有什么特点?
1.不需要自己创建子线程。
2.不需要考虑何时关闭服务。
使用情景是什么?
多次调用startService。
使用
1.Service继承IntentService。
2.以类名为参数调用父类构造方法。
3.重写onHandleIntent核心方法以及其他方法。

前台服务

什么是前台服务?
普通服务在内存不足的情况下会被系统杀掉,而前台服务不会因为内存不足而被杀掉。
前台服务有什么特点?
前台服务有通知栏提示,可设定相关的标题、提示灯。例如天气、播放器等。
前台服务的使用
1.构建Notification对象。
2.通过startForeground方法启动通知栏。
3.通过stopForeground方法关闭通知栏。
注意
Notification的构建中,若不调用setSmallIcon方法设置Icon,其他相关设置(标题、提示)均无效。

1234567891011121314151617
@Override   public int onStartCommand(final Intent intent, int flags, final int startId) {       final NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext());       builder.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(getApplicationContext(), MainActivity.class), 0));       builder.setContentTitle("前台服务");       //不知道什么鬼,不设置Icon,其他信息都不显示       builder.setSmallIcon(R.drawable.ic_menu_camera);       builder.setContentText("二级子标题");       builder.setSubText("三级子标题");       Notification notification = builder.build();       //开启通知栏提示       startForeground(startId, notification);       LogTool.e("CalcService", "onStartCommand");       Functions.toast("Service已启动,请查看LOG");       total = intent.getIntExtra("msg", 100);       return super.onStartCommand(intent, flags, startId);   }

Service官方文档
郭林大神ADIL服务
绑定服务

时间: 2024-12-22 07:38:17

Service的理解的相关文章

【Java】对Web Service的理解

WSDL(Web Service Description Language)是描述Web Service的语言. 你会怎样向别人介绍你的Web service有什么功能,以及每个函数调用时的参数呢?你可能会自己写一套文档,你甚至可能会口头上告诉需要使用你的Web service的人.这些非正式的方法至少都有一个严重的问题:当程序员坐到电脑前,想要使用你的Web service的时候,他们的工具(如Visual Studio)无法给他们提供任何帮助,因为这些工具根本就不了解你的Web servic

学习笔记dao,domain,service三层理解

1.dao层操作单表,不涉及复杂逻辑,主要是表的增删改查操作,完全根据domain的要求来查询数据,会对每个要操作的数据库表定义一个dao,对具体的操作要定义一个类似函数说明. eg: UppCodeInfo findByCodeNo(String codeNo);JPA方式 2.domain层考虑业务逻辑,例如过滤条件,放行或者返回,以及数据的处理,为调用dao层做好准备,一个domain可以调用一个或者一组相关的dao层. eg:@Entity         @Table(name = "

Java Web Action DAO Service层次理解

参考来源:http://blog.csdn.net/inter_peng/article/details/41021727 1. Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DAO只完成增删改查,虽然可以1-n,n-n,1-1关联,模糊.动态.子查询都可以.但是无论多么复杂的查询,dao只是封装增删改查.至于增删查改如何去实现一个功能,dao是不管的

Android service的理解

解析Service之你需要了解的一些东东 Android面试,与Service交互方式

Service的理解和使用

首先推荐一下郭林大神所讲的这一节的博客:http://blog.csdn.net/guolin_blog/article/details/11952435 下面结合我对这一部分的学习,自己做一个小节. Android5.0之后组件必须使用显示intent来启动,如果为隐示的,则设置Intent的包名.intent.setPackage("com.llay.admin.mydemo"); 一.基本概念 Service是一个应用程序组件,它能够在后台执行一些耗时较长的操作,并且不提供用户界

Springboot的entity,dao,controller,service层级理解

1.Dao层:持久层,主要与数据库交互 DAO层首先会创建Dao接口,接着就可以在配置文件中定义该接口的实现类:接着就可以在模块中调用Dao的接口进行数据业务的处理,而不用关注此接口的具体实现类是哪一个类,Dao层的数据源和数据库连接的参数都是在配置文件中进行配置的. 2.Entity层:实体层,数据库在项目中的类 主要用于定义与数据库对象应的属性,提供get/set方法,tostring方法,有参无参构造函数. 3.Service层:业务层 控制业务 业务模块的逻辑应用设计,和DAO层一样都是

web service的理解

http://blog.csdn.net/u011075267/article/details/41522643

关于Service中bindService注意的几个问题

最近有用到Activity需要不断的从Service中获取数据,第一个想法肯定就是通过bind回调机制了,有几点概念模糊特此记录下: 单独使用bindService(),unbindService()会经历:->onCreate()->onBind()->Service running->onUnbind() -> onDestroy() . 单独使用startService(),stopService()会经历:->onCreate()->onStartComm

Android应用开发基础篇(6)-----Service

链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/20/2360336.html 一.概述 我们知道,Service是Android的四大组件之一.在我看来,Service可以理解为一种在后台运行的服务,但它不是运行在一个独立的线程中,而是运行在主线程里,当程序有比较“繁重”的任务要执行时,就可以把它放在Service中执行.Service也有自己的生命周期,与Activity有点类似,但它没有用户界面,只在后台运行. 二.要求 编写一个带有S