当前位置:首页 » 安卓系统 » android中service的实现方法

android中service的实现方法

发布时间: 2022-01-09 01:49:44

⑴ android中如何自定义一个Service

在编写Android应用程序时,我们一般将一些计算型的逻辑放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通过startService函数来启动这个服务。在本文中,将详细分析主进程是如何通过startService函数来在新进程中启动自定义服务的。

⑵ android程序设计基础中service的基本原理是什么

1. 说明
android的后台运行在很多service,它们在系统启动时被SystemServer开启,支持系统的正常工作,比如MountService监听是否有SD卡安装及移除,ClipboardService提供剪切板功能,PackageManagerService提供软件包的安装移除及查看等等,应用程序可以通过系统提供的Manager接口来访问这些Service提供的数据,以下将说明他们的工具流程
2. 举例说明基本流程
以android系统支持sensor(传感器)实例来说明框架层的service和manager是如何配合工作的
1) 什么是sensor
sensor是传感器, 比如控制横竖屏切换利用的就是重力传感器(gsensor), 还有accelerator sensor可取得x, y, z三个轴上的加速度(应用如平衡球, 小猴吃香蕉等)
2) 应用程序调用(以下为关键代码)
sensorManager=(SensorManager)getSystemService(context.SENSOR_SERVICE);
lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
sensorManager.registerListener(sensorListener, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);
3) Manager层
a) 提供给应用程序调用的接口,同实与Service交互,实现功能
frameworks/base/core/java/android/hardware/SensorManager.java
4) Service层
a) 开机时就运行的管理Sensor的后台服务
frameworks/base/services/java/com/android/server/SensorService.java
b) snesor后台服务需要的JNI,通过它与系统级交互
frameworks/base/services/jni/com_android_server_SensorService.cpp
5) 系统层
a) 传感器的头文件,硬件提供商按此文件的定义实现其功能
hardware/libhardware/include/hardware/sensors.h
b) 传感器的系统层实现,与内核交互,此处通常是硬件提供商提供的
hareware/libsensors
6) 内核及硬件层
内核访问硬件,同时以设备文件等方式提供给上层控制接口和传感器数据
3. 系统层实现
1) frameworks/base/core/java/android/*Manager.java 对应用的接口
2) frameworks/base/core/jni/ 对应用的接口的JNI
3) frameworks/base/services/java/com/android/server/ 后台服务
4) frameworks/base/services/jni/ JNI与系统层接口
5) hardware/libhardware/include/ 系统层头文件
6) hardware/libxxx 系统库支持
7) 内核支持
4. 应用程序如何使用
1) 查看系统提供哪些服务
find frameworks/base/core/java/android/ -name *Manager.java
此处可以看到调用系统提供服务的入口
2) 一般register listener,事件发生时都收到回调
5. 新建一个service(以froyo为例)
1) 接口:接口供应用调用
frameworks/base/core/java/android/app/ContextImpl.java 加服务名与Manager对应
frameworks/base/core/java/android/content/Context.java 加服务名定义
2) Manager:提供服务对应的调用接口
frameworks/base/core/java/android/app/StartXXXXManager.java 实现调用接口
frameworks/base/core/java/android/app/IXXXXManager.aidl 定义调用接口
frameworks/base/Android.mk 加入aidl的编译
3) service:提供后台服务支持
frameworks/base/services/java/com/android/server/XXXXService.java 服务实现
frameworks/base/services/java/com/android/server/SystemServer.java 启动服务

⑶ android中怎么启动service

1、 Service不是分离开的进程,除非其他特殊情况,它不会运行在自己的进程,而是作为启动运行它的进程的一部分。 2、 Service不是线程,这意味着它将在主线程里劳作。 启动service有两种方法: 1、 Context.startService() 调用者与服务之间没有关联,即使调用者退出,服务仍可运行 2、 Context.bindService() 调用者与服务绑定在一起,调用者一旦退出,服务也就终止 Service的生命周期 如果使用startService()启动service,系统将通过传入的Intent在底层搜索相关符合Intent里面信息的service。如果 服务没有启动则先运行onCreate,然后运行onStartCommand (可在里面处理启动时传过来的Intent和其他参数),直到明显调用stopService或者stopSelf才将停止Service。无论运行 startService多少次,只要调用一次stopService或者stopSelf,Service都会停止。使用stopSelf(int)方 法可以保证在处理好intent后再停止。 控制service运行的主要方式有两种,主要是根据onStartCommand方法返回的数值。方法: 1、START_STICKY 2、START_NOT_STICKY or START_REDELIVER_INTENT 这里主要解释这三个变量的意义: 1、 START_STICKY 在运行onStartCommand后service进程被kill后,那将保留在开始状态,但是不保留那些传入的intent。不久后service就 会再次尝试重新创建,因为保留在开始状态,在创建 service后将保证调用onstartCommand。如果没有传递任何开始命令给service,那将获取到null的intent 2、 START_NOT_STICKY 在运行onStartCommand后service进程被kill后,并且没有新的intent传递给它。Service将移出开始状态,并且直到新的 明显的方法(startService)调用才重新创建。因为如果没有传递任何未决定的intent那么service是不会启动,也就是期间 onstartCommand不会接收到任何null的intent。 3、 START_REDELIVER_INTENT 在运行onStartCommand后service进程被kill后,系统将会再次启动service,并传入最后一个intent给 onstartCommand。直到调用stopSelf(int)才停止传递intent。如果在被kill后还有未处理好的intent,那被 kill后服务还是会自动启动。因此onstartCommand不会接收到任何null的intent。 客户端也可以使用bindService来保持跟service持久关联。谨记:如果使用这种方法,那么将不会调用onstartCommand(跟 startService不一样,下面例子注释也有解析,大家可试试)。客户端将会在onBind回调中接收到IBinder接口返回的对象。通常 IBinder作为一个复杂的接口通常是返回aidl数据。 Service也可以混合start和bind一起使用。 权限 要运行service,首先必须在AndroidManifest.xml里申明<service>标签。 Service能够保护个人的IPC调用,所以在执行实现该调用时前先使用checkCallingPermission(String) 方法检查是否有这个权限。

⑷ Android开发,怎么在service中实现 oncreat方法创建子线程,onstart里实现子线程逻辑

创建线程后,在run, while(true){ xxx()} xxx(){ if(?)xxxx ?=false} ,onstart(){? = true}
这样能否行.. 要不然你就每次都重新创建线程发送socket..

⑸ Android Service启动方式

1.startService
①.定义一个类继承service
②.在manifest.xml文件中配置该service
③.使用context的startService(intent)启动该service
④.不再使用时,调用stopService(Intent)停止该服务
2.bindService
①.创建bindService服务段,继承自service并在类中,创建一个实现binder接口的实例对象并提供公共方法给客户端调用
②.从onbind()回调方法返回此binder实例
③.在客户端中,从onserviceconnected()回调方法接收binder,并使用提供的方法调用绑定服务

⑹ android中service的实现方法是

异步执行
android中,activity、service都是在主线程,service与activity的主要区别就是service没有前台界面,不能直接与用户交互,另外可以相对保证不会被系统随便的kill掉。所以service适用于一些无需交互的后台操作,但如果你直接在service中进行耗时操作的话,因为在主线程所以依然会出现和activity主线程一样的超时的问题,所以好的方式是在service中启动其他的线程去执行耗时操作。

⑺ Android中如何启用Service,如何停用Service

• Context.startService()
• Context.bindService()

1. 在同一个应用任何地方调用 startService() 方法就能启动 Service 了,然后系统会回调 Service 类的
onCreate() 以及 onStart() 方法。这样启动的 Service 会一直运行在后台,直到
Context.stopService() 或者 selfStop() 方法被调用。另外如果一个 Service 已经被启动,其他代码再试图调用
startService() 方法,是不会执行 onCreate() 的,但会重新执行一次 onStart() 。

2. 另外一种 bindService() 方法的意思是,把这个 Service 和调用 Service
的客户类绑起来,如果调用这个客户类被销毁,Service 也会被销毁。用这个方法的一个好处是,bindService() 方法执行后
Service 会回调上边提到的 onBind() 方发,你可以从这里返回一个实现了 IBind
接口的类,在客户端操作这个类就能和这个服务通信了,比如得到 Service 运行的状态或其他操作。如果 Service
还没有运行,使用这个方法启动 Service 就会 onCreate() 方法而不会调用 onStart()。

总结:
1.
startService()的目的是回调onStart()方法,onCreate()
方法是在Service不存在的时候调用的,如果Service存在(例如之前调用了bindService,那么Service的onCreate方法
已经调用了)那么startService()将跳过onCreate() 方法。

2.
bindService()目的是回调onBind()方法,它的作用是在Service和调用者之间建立一个桥梁,并不负责更多的工作(例如一个
Service需要连接服务器的操作),一般使用bindService来绑定到一个现有的Service(即通过StartService启动的服
务)。
由于Service 的onStart()方法只有在startService()启动Service的情况下才调用,故使用onStart()的时候要注意这点。

⑻ 安卓怎么获取service的方法

onBind里不是要返回一个IBinder 你在IBinder里写一个get方法, return Service.this即可啊, 通常情况下不会这么说, 与service通信只需要用这个binder即可 , 双向通信都可以用这个binder进行的.
追问: 我在其他页面怎么调用这个onBind方法啊?
追答: 只能在绑定这个sevice的地方调用噢
追问: 那其他界面没绑定这个service的话,就要绑定了才可以调用?
追答: 那肯定的啊, 你这种设计就有问题, 多个activity为什么要去调用这个service呢
追问: 是这样,我现在要开发一个蓝牙连接打印机的APP,然后手机控制打印机打印东西,我在这个界面去连接好打印机后,在其他页面去设置打印的东西,比如在A界面打印超市小票,B界面打印二维码图片什么的,所以就需要在A界面调用连接打印机的这个service去发送数据给打印机,在B界面也可以调用。那我现在就是哪里需要发送数据给打印机,哪里就要绑定一下那个service?
追答: 每个界面都要绑定

⑼ android servicemanager 怎么实现service管理

ServiceManager是android中比较重要的一个进程,它是在init进程启动之后启动,从名字上就可以看出来它是用来管理系统中的service。比如:InputMethodService、ActivityManagerService等。在ServiceManager中有两个比较重要的方法:add_service、check_service。系统的service需要通过add_service把自己的信息注册到ServiceManager中,当需要使用时,通过check_service检查该service是否存在。


主函数(anrdroid4.0/frameworks/base/cmds/servicemanager/service_manager.c)


从它的主函数代码开始:


int main(int argc, char **argv)

{

struct binder_state *bs;

void *svcmgr = BINDER_SERVICE_MANAGER;

bs = binder_open(128*1024);

if (binder_become_context_manager(bs)) {

LOGE("cannot become context manager (%s) ", strerror(errno));

return -1;

}

svcmgr_handle = svcmgr;

binder_loop(bs, svcmgr_handler);

return 0;

}

从main函数中可以看出,它主要做了三件事情:


打开/dev/binder设备,并在内存中映射128K的空间。

通知Binder设备,把自己变成context_manager

进入循环,不停的去读Binder设备,看是否有对service的请求,如果有的话,就去调用svcmgr_handler函数回调处理请求。

服务注册


再来看看ServiceManager中是怎么样去注册服务的。先来看先,当有对service的请求时,调用的回调函数svcmgr_handler:


int svcmgr_handler(struct binder_state *bs,

struct binder_txn *txn,

struct binder_io *msg,

struct binder_io *reply)

{

struct svcinfo *si;

uint16_t *s;

unsigned len;

void *ptr;

uint32_t strict_policy;

// LOGI("target=%p code=%d pid=%d uid=%d ",

// txn->target, txn->code, txn->sender_pid, txn->sender_euid);

if (txn->target != svcmgr_handle)

return -1;

// Equivalent to Parcel::enforceInterface(), reading the RPC

// header with the strict mode policy mask and the interface name.

// Note that we ignore the strict_policy and don't propagate it

// further (since we do no outbound RPCs anyway).

strict_policy = bio_get_uint32(msg);

s = bio_get_string16(msg, &len);

if ((len != (sizeof(svcmgr_id) / 2)) ||

memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {

fprintf(stderr,"invalid id %s ", str8(s));

return -1;

}

switch(txn->code) {

case SVC_MGR_GET_SERVICE:

case SVC_MGR_CHECK_SERVICE:

s = bio_get_string16(msg, &len);

ptr = do_find_service(bs, s, len);

if (!ptr)

break;

bio_put_ref(reply, ptr);

return 0;

case SVC_MGR_ADD_SERVICE:

s = bio_get_string16(msg, &len);

ptr = bio_get_ref(msg);

if (do_add_service(bs, s, len, ptr, txn->sender_euid))

return -1;

break;

case SVC_MGR_LIST_SERVICES: {

unsigned n = bio_get_uint32(msg);

si = svclist;

while ((n-- > 0) && si)

si = si->next;

if (si) {

bio_put_string16(reply, si->name);

return 0;

}

return -1;

}

default:

LOGE("unknown code %d ", txn->code);

return -1;

}

bio_put_uint32(reply, 0);

return 0;

}

在该回调函数中会判断Service有什么需要,如果是请求注册service,那么久执行:


case SVC_MGR_ADD_SERVICE:

s = bio_get_string16(msg, &len);

ptr = bio_get_ref(msg);

if (do_add_service(bs, s, len, ptr, txn->sender_euid))

return -1;

break;

我们再来看看do_add_service中做了什么事情:


int do_add_service(struct binder_state *bs,

uint16_t *s, unsigned len,

void *ptr, unsigned uid)

{

struct svcinfo *si;

// LOGI("add_service('%s',%p) uid=%d ", str8(s), ptr, uid);

if (!ptr || (len == 0) || (len > 127))

return -1;

if (!svc_can_register(uid, s)) {

LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED ",

str8(s), ptr, uid);

return -1;

}

si = find_svc(s, len);

if (si) {

if (si->ptr) {

LOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED ",

str8(s), ptr, uid);

return -1;

}

si->ptr = ptr;

} else {

si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));

if (!si) {

LOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY ",

str8(s), ptr, uid);

return -1;

}

si->ptr = ptr;

si->len = len;

memcpy(si->name, s, (len + 1) * sizeof(uint16_t));

si->name[len] = '';

si->death.func = svcinfo_death;

si->death.ptr = si;

si->next = svclist;

svclist = si;

}

binder_acquire(bs, ptr);

binder_link_to_death(bs, ptr, &si->death);

return 0;

}

在该函数中,首先会去检查是否有权限注册service,如果没有权限就直接返回,不能注册。


if (!svc_can_register(uid, s)) {

LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED ",

str8(s), ptr, uid);

return -1;

}

然后会去检查该service是否已经注册过了,如果已经注册过,那么就不能再注册了:


si = find_svc(s, len);

if (si) {

if (si->ptr) {

LOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED ",

str8(s), ptr, uid);

return -1;

}

si->ptr = ptr;

}

再判断内存是否足够:


si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));

if (!si) {

LOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY ",

str8(s), ptr, uid);

return -1;

}

如果都没什么问题,会注册该service,加入到svcList中来。注意,在ServiceManager中维护service信息的地方就是svclist。里面存了service的name和handler。


服务获取


通过以上几个步骤,service就算注册成功了。那么当要获得该service的时候又是怎么去处理的。还是来看下回调函数中的判断:


case SVC_MGR_CHECK_SERVICE:

s = bio_get_string16(msg, &len);

ptr = do_find_service(bs, s, len);

if (!ptr)

break;

bio_put_ref(reply, ptr);

return 0;


如果是获取service,那么执行SVC_MGR_CHECK_SERVICE,并把返回的数据写入reply,返回给客户端。


do_find_service函数中主要执行service的查找。


void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len)

{

struct svcinfo *si;

si = find_svc(s, len);

// LOGI("check_service('%s') ptr = %p ", str8(s), si ? si->ptr : 0);

if (si && si->ptr) {

return si->ptr;

} else {

return 0;

}

}

这样在ServiceManager中就完成了服务的注册和查找。来看下ServiceManager的功能图:

转载

⑽ android 启动service的两种方式有什么不同

Service的生命周期Service的生命周期方法比Activity少一
些,只有onCreate,onStart,onDestroy
我们有两种方式启动一个Service,他们对Service生命周期
的影响是不一样的。
1;通过startService:
Service会经历onCreate->onStart,
stopService的时候直接onDestroy如果是调用者(TestServiceHolder)自己直接退出而没有调用stopService的话,Service会一直在后台运行。下次TestServiceHolder再起来可以stopService。
2:通过bindService:
Service只会运行onCreate,这个时候TestServiceHolder和TestService绑定在一起
TestServiceHolder退出了,Srevice就会调用onUnbind->onDestroyed所谓绑定在一起就共存亡了。
那有同学问了,要是这几个方法交织在一起的话,会出现什么情况呢?
一个原则是Service的onCreate的方法只会被调用一次,就是你无论多少次的
startService又bindService,Service只被创建一次。如果先是bind了,那么start的时候就直接运行Service的onStart方法,如果先是start,那么bind的时候就直接运行onBind方法。如果你先bind上了,就
stop不掉了,对啊,就是stopService不好使了,只能先UnbindService,再StopService,
所以是先start还是先bind行为是有区别的。

热点内容
海康威视存储卡质量如何 发布:2024-09-19 08:55:35 浏览:939
python3默认安装路径 发布:2024-09-19 08:50:22 浏览:516
环卫视频拍摄脚本 发布:2024-09-19 08:35:44 浏览:418
sqlserveronlinux 发布:2024-09-19 08:16:54 浏览:256
编程常数 发布:2024-09-19 08:06:36 浏览:952
甘肃高性能边缘计算服务器云空间 发布:2024-09-19 08:06:26 浏览:162
win7家庭版ftp 发布:2024-09-19 07:59:06 浏览:717
数据库的优化都有哪些方法 发布:2024-09-19 07:44:43 浏览:269
知乎华为编译器有用吗 发布:2024-09-19 07:32:20 浏览:618
访问虚拟机磁盘 发布:2024-09-19 07:28:13 浏览:670