Android系统是一个基于BInder通信的C/S架构
Android系统基本上可以看作是一个基于Binder通信的C/S架构。他有服务器端和客户端。比如自己开发一个程序,肯定是基于Activity的而Activity就是作为客户端,他的服务器端就是ActivityManagerService。
1.Activity客户端和他的服务器ActivityManagerService通信
客户端和服务器通信都是客户端发出请求,由服务器端来响应的,比如WWW服务就是客户端先知道服务器的地址,然后就可以通过浏览器来访问了。首先我们假设客户端知道服务器的地址(实际上是代理,先不考虑),当Activity要启动的时候,就告诉服务器要求启动,然后服务器就开始启动Activity。
Intent intent =new Intent(this, FirstActivity.class);//FirstActivity携带者APK安装包的信息,在Android目录结构的时候会详细介绍
Bundle bundle=new Bundle();
bundle.putString("test", "FirstActivity Bundle传值");
startActivity(intent);#向服务器发送请求要求启动FirstActivity.class
web客户端能让服务器正确启动是因为有一个唯一不重复的URL来标识命令的。Android这个C/S服务也是一样的,Intent在Android也是唯一的。Intent携带的FirstActivity的信息可以唯一的定位到一个Activity的。(PackageManger通过Parse每个Application的AndroidManifest.xml文件,能获得所有Activity的信息,只要把Intent交给PackageManager就可以唯一的定位到一个Activity了。针对每个Intent提供的信息,PM会提供给AMS一个ResolveInfo对象)。就像WWW服务会有很多客户端一样,AMS提供了一个ArrayList mHIstory来管理所有的activity,Activity在AMS中的形式是ActivityRecord。知识拓展:android Application Component研究之Activity(一)
2.Service客户端和他的服务器ServiceManger的通信
Service也是有自己的服务器端的就是ServiceManger,这个并不是SystemService提供的服务而是linux init加载的第一个进程,是用来管理服务的,SystemService是java包装的管理系统核心服务的服务,并不是所有的服务都能注册到systemService里的,哪些不能注册的都是由ServiceManger在管理。当然ServiceManger不是java实现的。知识扩展:android service 启动过程 当Service发出startService请求的时候,ServiceManager就会根据Intent找到Service文件的位置,并加载到内存中,如果加载成功就会调用ServiceConnection方法,如果连接建立就会执行 否则就会执行onServiceConnected(ComponentName name, IBinder service)方法,如果连接失败就会执行onServiceDisconnected(ComponentName name)方法。类比Socket通讯连接建立后就是往客户端的Socket写入信息,这里也是如果和服务器建立了连接就会往发送一个服务器端的引用,然后客户端就可以像使用自己的功能一样使用服务端的功能了。
package com.example.servicedemo3; import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu; public class MainActivity extends Activity { ServiceConnection connection =new ServiceConnection() { //调用connection是由ServiceManger来调用的,试想这个代码里我们没有在OnCreate方法里调用ServiceConnection,那为什么就能连接服务器哪,现在服务器还没有联通更不可能是服务器调用到自己的连接,不是客户端调用不是服务器端调用自然就是第三方ServieManger调用了。 @Override
public void onServiceDisconnected(ComponentName name) { //现在服务器连接已经失败了,服务器什么也做不了了
} @Override
public void onServiceConnected(ComponentName name, IBinder service) {
ServiceDemo.MyBlinder mb =(ServiceDemo.MyBlinder)service; //调用成功后就会通过BInder来通讯,所以这里的数据是服务器可以作用的了
mb.checkWifi(); }
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// bindService(new Intent(MainActivity.this, ServiceDemo.class), connection, BIND_AUTO_CREATE); startService(new Intent(this, ServiceDemo.class)); //向ServieManger申请启动Service } @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }
服务端:
package com.example.servicedemo3; import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log; public class ServiceDemo extends Service { @Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.d("Start COmmand","Startcommad 调用");
return super.onStartCommand(intent, flags, startId);
} @Override
public IBinder onBind(Intent intent) { //客户端能获得的引用就是这里返回的,也就是这里如同给客户端写数据的ServiceSocket了
// TODO Auto-generated method stub
return new MyBlinder(); } class MyBlinder extends Binder{ //这里就是服务器端的功能调用 public void checkWifi(){ System.out.println("----------------------------");
System.out.println("------------CheckWIfi----------------");
Log.d("CHeckWIFT","Service------------------"); } } }
3.为什么服务器不是直接和客户端通讯要通过第三方?
Android内部不是只有一个服务几个客户端,一个服务或很少服务的时候,客户端能直接访问服务器的前提知道服务器的URL,也就是像WWW这中服务,服务是事先对外生命了确定的服务端口的,所以客户端可以直接访问。但是Android有这么多的服务,如果每个都对外声明一个端口那么这个表是非常庞大的,并且一般分配无法动态回收的,所以这样这个系统实现起来是很不好的,关键还是对外暴露了过多的访问端口,对系统的安全性和API的复杂度影响很大。而用了ServiceManger(主要是Linux)和SystemServie(java时间的核心服务管理)和MediaServer就等同于对外没有暴露很多的端口,而是暴露了这很少的几个,只要把需求告诉ServiceManager,他就会匹配自己管理的服务对外端口,然后返回给你,然后让服务器和客户端正常通信就可以了。
Android系统是一个基于BInder通信的C/S架构的更多相关文章
- 「Android」 基于Binder通信的C/S架构体系认知
C/S架构(Client/Server,即客户机/服务器模式)分为客户机和服务器两层:第一层是在客户机系统上结合了表示与业务逻辑,第二层是通过网络结合了数据库服务器.简单的说就是第一层是用户表示层,第 ...
- 转: Orz是一个基于Ogre思想的游戏开发架构
Orz是一个基于Ogre思想的游戏开发架构,好的结构可以带来更多的功能.Orz和其他的商业以及非商业游戏开发架构不同.Orz更专著于开发者的感受,简化开发者工作.Orz可以用于集成其他Ogre3D之外 ...
- [系统开发] 一个基于Django和PureCSS的内容管理系统
这是我刚开发的一套基于Django和PureCSS的内容管理系统,目标是优雅.简洁.实用,目前功能还在完善中. 系统参考了网上的教程,除了文章管理.搜索.RSS,还增加了类别管理.用户管理,以及评论管 ...
- android与C# WebService基于ksoap通信(C#篇)
1.打开VS 2013新建项目>>ASP.NET空WEB应用程序(我用的是.net 4.0) 2.在刚建立的项目上加入新建项(WebService) 这时TestService的代码例如以 ...
- Android系统Binder机制学习总结
一.Binder机制概述 在Android开发中,很多时候我们需要用到进程间通信,所谓进程间通信,实现进程间通信的机制有很多种,比如说socket.pipe等,Android中进程间通信的方式主要有三 ...
- 【转】Android系统开篇
版权声明:本站所有博文内容均为原创,转载请务必注明作者与原文链接,且不得篡改原文内容.另外,未经授权文章不得用于任何商业目的. 一.引言 Android系统非常庞大.错综复杂,其底层是采用Linux作 ...
- 【转】Android系统概览
这篇文章其实原文叫 <老罗的Android之旅>导读PPT 是罗升阳的博客,我觉得用“Android系统概览”作为标题更贴切些,对于在应用层已经开发了一段时间的人来说,读完之后会有很多体会 ...
- 如何学习Android系统源码(转)
一. Android系统的源代码非常庞大和复杂,我们不能贸然进入,否则很容易在里面迷入方向,进而失去研究它的信心.我们应该在分析它的源代码之前学习好一些理论知识,下面就介绍一些与Android系统相关 ...
- 深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一
作者:唐老师,华清远见嵌入式学院讲师. 1. Sensor的概念 Sensor即传感器,在当前智能手机上大量存在:G-Sensor.LightsSensor. ProximitySensor.Temp ...
随机推荐
- PyTorch深度学习计算机视觉框架
Taylor Guo @ Shanghai - 2018.10.22 - 星期一 PyTorch 资源链接 图像分类 VGG ResNet DenseNet MobileNetV2 ResNeXt S ...
- PAT——乙级1022:D进制的A+B &乙级1037:在霍格沃茨找零钱
1022 D进制的A+B (20 point(s)) 输入两个非负 10 进制整数 A 和 B (≤230−1),输出 A+B 的 D (1<D≤10)进制数. 输入格式: 输入在一行中依 ...
- kvm-1
yum install libvirt* virt-* qemu-kvm* -y systemctl start libvirtd.service systemctl status libvirtd. ...
- Python-爬取"我去图书馆"座位编码
原文地址:http://fanjiajia.cn/2018/11/22/Python-%E7%88%AC%E5%8F%96%E2%80%9D%E6%88%91%E5%8E%BB%E5%9B%BE%E4 ...
- hdu2421(数学,因式分解素数筛)
Xiaoming has just come up with a new way for encryption, by calculating the key from a publicly view ...
- Android 实现异步加载图片
麦洛开通博客以来,有一段时间没有更新博文了.主要是麦洛这段时间因项目开发实在太忙了.今天周六还在公司加班,苦逼程序猿都是这样生活的. 今天在做项目的时候,有一个实现异步加载图片的功能,虽然比较简单但还 ...
- NIO Q&A(持续补充。。。。)
Q:NIO是非阻塞的.但调用的selector.select()方法会阻塞.这和NIO非阻塞岂不是矛盾了? A:非阻塞指的是 IO 事件本身不阻塞,但是获取 IO 事件的 select 方法是需要阻塞 ...
- 你对javascript的原生操作或者工具了解多少呢?
1.有一个长度未知的数组a,如果它的长度为0就把数字1添加到数组里面,否则按照先进先出的队列规则让第一个元素出队. 分析:这道题主要是考核了数组的队列方法和栈方法.另外,原题还有字数限制的,只有在字数 ...
- POJ2594:Treasure Exploration(Floyd + 最小路径覆盖)
Treasure Exploration Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 9794 Accepted: 3 ...
- 安卓下拉刷新空间SwipeRefreshLayout的基本使用
1.先写布局文件 <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/refresh" androi ...