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 ...
随机推荐
- Linux 简单socket实现TCP通信
服务器端代码 #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <stri ...
- 搭建ELK 6
ELK 6.2.4搭建 https://www.cnblogs.com/harvey2017/p/8922164.html 开源实时日志分析ELK平台能够完美的解决我们上述的问题,ELK由Elasti ...
- NIO Q&A(持续补充。。。。)
Q:NIO是非阻塞的.但调用的selector.select()方法会阻塞.这和NIO非阻塞岂不是矛盾了? A:非阻塞指的是 IO 事件本身不阻塞,但是获取 IO 事件的 select 方法是需要阻塞 ...
- hdu DIY FLIGHT GAME (dfs)
FLIGHT GAME Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total S ...
- [Leetcode] combinations 组合
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For exampl ...
- 怎么将数据库从Oracle迁移到SQL Server,或从Oracle迁移到MySQL
有时候我们有迁移数据库的需求,例如从Oracle迁移到SQL Server,或者从MySQL迁移到Oracle. 很多江湖好汉一时不知如何手工操作,所幸的是Navicat提供了迁移的自动化操作界面. ...
- TCP ------ RST的产生
产生RST的几个原因 1.请求超时 有89.27两台主机.主机89向主机27发送了一个SYN,表示希望连接8888端口,主机27回应了主机89一个SYN表示可以连接.但是主机89莫名其妙的发送了一个R ...
- namenode磁盘满引发recover edits文件报错
前段时间公司hadoop集群宕机,发现是namenode磁盘满了, 清理出部分空间后,重启集群时,重启失败. 又发现集群Secondary namenode 服务也恰恰坏掉,导致所有的操作log持续写 ...
- i=i+1与i+=1的区别及效率(Java)
原博客地址 在做个java优化的PPT时,看到了i=i+1与i+=1的区别,在这之前还真没想到那么细. 1.x=x+1,x+=1及x++的效率哪个最高?为什么? x=x+1最低,因为它的执行如下. ( ...
- Spring学习-- Bean 的作用域
Bean 的作用域: 在 Spring 中 , 可以在 <bean> 元素的 scope 属性里设置 bean 的作用域. 默认情况下 , Spring 只为每个在 IOC 容器里声明的 ...