Android Service组件在新进程绑定(bindService)过程
1、首先看两个样例
(1)进程内
Client端
public class CounterService extends Service implements ICounterService {
...... public class CounterBinder extends Binder {
public CounterService getService() {
return CounterService.this;
}
} ......
}
Server端
public class MainActivity extends Activity implements OnClickListener {
...... private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
counterService = ((CounterService.CounterBinder)service).getService(); Log.i(LOG_TAG, "Counter Service Connected");
}
......
}; ......
}
(1)进程间
Client端
public class RemoteService extends Service {
private final static String TAG = "RemoteService";
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "运行了OnBind");
return new MyBinder();
} private class MyBinder extends RemoteWebPage.Stub{
@Override
public String getCurrentPageUrl() throws RemoteException{
return "http://www.cnblogs.com/hibraincol/";
}
}
}
Server端
private class MyServiceConnection implements ServiceConnection{ @Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "建立连接...");
remoteWebPage = RemoteWebPage.Stub.asInterface(service);
try {
Log.d(TAG, remoteWebPage.getCurrentPageUrl());
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } @Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "onServiceDisconnected...");
}
}
为什么一个是
counterService = ((CounterService.CounterBinder)service).getService();
还有一个是
remoteWebPage = RemoteWebPage.Stub.asInterface(service);
原因在于第一个service是CounterService对象,第二个Service是BinderProxy对象,指向MyBinder对象。
为什么进程内和进程间会有区别呢?请看下图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamx0eGdjeQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
就在于第6步,要传递的參数是BinderProxy对象。
进程内会运行例如以下代码:
case BINDER_TYPE_HANDLE:
case BINDER_TYPE_WEAK_HANDLE: {
struct binder_ref *ref = binder_get_ref(proc, fp->handle);
...........
if (ref->node->proc == target_proc) {//同样进程
if (fp->type == BINDER_TYPE_HANDLE)
fp->type = BINDER_TYPE_BINDER;
else
fp->type = BINDER_TYPE_WEAK_BINDER;
fp->binder = ref->node->ptr;
fp->cookie = ref->node->cookie;
binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
printk(KERN_INFO " ref %d desc %d -> node %d u%p\n",
ref->debug_id, ref->desc, ref->node->debug_id, ref->node->ptr);
} else {
......
}
}
为转换成CounterService对象做准备。
进程间会运行例如以下代码:
case BINDER_TYPE_HANDLE:
case BINDER_TYPE_WEAK_HANDLE: {
struct binder_ref *ref = binder_get_ref(proc, fp->handle);
.........
if (ref->node->proc == target_proc) {
.....
} else {//不同进程
struct binder_ref *new_ref;
new_ref = binder_get_ref_for_node(target_proc, ref->node);
if (new_ref == NULL) {
return_error = BR_FAILED_REPLY;
goto err_binder_get_ref_for_node_failed;
}
fp->handle = new_ref->desc;
binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
printk(KERN_INFO " ref %d desc %d -> ref %d desc %d (node %d)\n",
ref->debug_id, ref->desc, new_ref->debug_id, new_ref->desc, ref->node->debug_id);
}
}
为转换成BinderProxy对象做准备。
此时BinderProxy对象是Counter进程的。MyBinder对象是CounterService进程的。它们通过进程间通信的方式传递数据。
Android Service组件在新进程绑定(bindService)过程的更多相关文章
- Android组件系列----Android Service组件深入解析
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- Android Service组件(1)
android service 和其他服务一样,并没有实际运行的界面,它运行在android 后台.一般通过service为应用程序提供服务(比如,从Internet下载文件,控制音乐播放器等).Se ...
- Android四大组件与进程启动的关系(转)
一. 概述 Android系统将进程做得很友好的封装,对于上层app开发者来说进程几乎是透明的. 了解Android的朋友,一定知道Android四大组件,但对于进程可能会相对较陌生. 一个进程里面可 ...
- ATMS中去拉起新的进程,并在新进程启动后调用attachApplication时,resume待启动的Activity
相关文章: ATMS中去pause Activity A. 目录 ATMS拉起新进程 堆栈 resumeTopActivityInnerLocked:1684, ActivityStack start ...
- linux内核分析第六周-分析Linux内核创建一个新进程的过程
Linux内核对进程管理是操作系统的重要任务之一. 此次实验就是了解内核创建一个新进程的大致过程. 为了简单,使用fork再用户态创建一个进程.代码如下: 下面是准备工作 cd LinuxKer ...
- Go:创建新进程(os.StartProcess源码解读)
关于如何使用go语言实现新进程的创建和进程间通信,我在网上找了不少的资料,但是始终未能发现让自己满意的答案,因此我打算自己来分析这部分源代码,然后善加利用,并且分享给大家,期望大家能从中获得启发. 首 ...
- Android4.4 Framework分析——Zygote进程的启动过程
Android启动过程中的第一个进程init.在启动过程中会启动两个关键的系统服务进程ServiceManager和Zygote. 本文要介绍的就是Zygote进程的启动,Zygote俗称孵化器,专门 ...
- Android 四大组件之再论service
service常见的有2种方式,本地service以及remote service. 这2种的生命周期,同activity的通信方式等,都不相同. 关于这2种service如何使用,这里不做介绍,只是 ...
- Android 四大组件之二(Service)
service可以在和多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务 ...
随机推荐
- Problem A: 求平均年龄
Description 定义一个Persons类,用于保存若干个人的姓名(string类型)和年龄(int类型),定义其方法 void addAPerson(string,int) 用于添加1个人的信 ...
- zip 安装mysql 和遇到的坑
在官网下载了mysql 社区版的,官方网址:https://dev.mysql.com/downloads/mysql/ 解压后发现里面没有安装快捷方式,才知道是zip解压,dos窗口安装.这就比界面 ...
- JavaScript 数组基本操作
简介 数组操作无论是在JavaScript中还是在其他语言中都是很常见.经常会用到的,现在我把JavaScript 数组基本操作整理一下,供大家参考学习.里边包含我自己的见解以及案例,希望能够帮助大家 ...
- 设计模式的征途—23.解释器(Interpreter)模式
虽然目前计算机编程语言有好几百种,但有时人们还是希望用一些简单的语言来实现特定的操作,只需要向计算机输入一个句子或文件,就能按照预定的文法规则来对句子或文件进行解释.例如,我们想要只输入一个加法/减法 ...
- redis特性 存储 API 集群 等
公司组内技术分享,刚好最近工作用redis构建缓存,所以想同事们分享关于redis的一些知识, 这些知识不仅仅是包括一些API层,而是一些关于redis功能功能特性的 目前为什么使用redis构建缓存 ...
- FPGA时钟分频(转)
http://www.cnblogs.com/fpga/archive/2009/10/24/1589318.html 占空比为50%的分频 偶数分频比较简单 比如N分频,那么计数到N/2-1,然后时 ...
- mysql数据库常用命令笔记
连接数据库:mysql -h localhost -u root -p 000000 退出:exit; \q; quit; SET foreign_key_checks = 0; 禁用外键 ...
- alex python of day2
模块 sys模块:sys模块是用c语言写的,所以在lib下是不会有sys.py这个文件存在 1 import sys 2 print(sys.path) #打印环境变量 3 print(sys.a ...
- vim操作命令
一,命令模式下 文件顶部: gg 文件底部: G 删除当前行:dd 删除当前行,并进入INSERT模式: cc 取消删除:u
- CentOS7.2非HA分布式部署Openstack Pike版 (实验)
部署环境 一.组网拓扑 二.设备配置 笔记本:联想L440处理器:i3-4000M 2.40GHz内存:12G虚拟机软件:VMware® Workstation 12 Pro(12.5.2 build ...