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架构的更多相关文章

  1. 「Android」 基于Binder通信的C/S架构体系认知

    C/S架构(Client/Server,即客户机/服务器模式)分为客户机和服务器两层:第一层是在客户机系统上结合了表示与业务逻辑,第二层是通过网络结合了数据库服务器.简单的说就是第一层是用户表示层,第 ...

  2. 转: Orz是一个基于Ogre思想的游戏开发架构

    Orz是一个基于Ogre思想的游戏开发架构,好的结构可以带来更多的功能.Orz和其他的商业以及非商业游戏开发架构不同.Orz更专著于开发者的感受,简化开发者工作.Orz可以用于集成其他Ogre3D之外 ...

  3. [系统开发] 一个基于Django和PureCSS的内容管理系统

    这是我刚开发的一套基于Django和PureCSS的内容管理系统,目标是优雅.简洁.实用,目前功能还在完善中. 系统参考了网上的教程,除了文章管理.搜索.RSS,还增加了类别管理.用户管理,以及评论管 ...

  4. android与C# WebService基于ksoap通信(C#篇)

    1.打开VS 2013新建项目>>ASP.NET空WEB应用程序(我用的是.net 4.0) 2.在刚建立的项目上加入新建项(WebService) 这时TestService的代码例如以 ...

  5. Android系统Binder机制学习总结

    一.Binder机制概述 在Android开发中,很多时候我们需要用到进程间通信,所谓进程间通信,实现进程间通信的机制有很多种,比如说socket.pipe等,Android中进程间通信的方式主要有三 ...

  6. 【转】Android系统开篇

    版权声明:本站所有博文内容均为原创,转载请务必注明作者与原文链接,且不得篡改原文内容.另外,未经授权文章不得用于任何商业目的. 一.引言 Android系统非常庞大.错综复杂,其底层是采用Linux作 ...

  7. 【转】Android系统概览

    这篇文章其实原文叫 <老罗的Android之旅>导读PPT 是罗升阳的博客,我觉得用“Android系统概览”作为标题更贴切些,对于在应用层已经开发了一段时间的人来说,读完之后会有很多体会 ...

  8. 如何学习Android系统源码(转)

    一. Android系统的源代码非常庞大和复杂,我们不能贸然进入,否则很容易在里面迷入方向,进而失去研究它的信心.我们应该在分析它的源代码之前学习好一些理论知识,下面就介绍一些与Android系统相关 ...

  9. 深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一

    作者:唐老师,华清远见嵌入式学院讲师. 1. Sensor的概念 Sensor即传感器,在当前智能手机上大量存在:G-Sensor.LightsSensor. ProximitySensor.Temp ...

随机推荐

  1. UVa 294 - Divisors 解题报告 c语言实现 素数筛法

    1.题目大意: 输入两个整数L.H其中($1≤L≤H≤10^9,H−L≤10000$),统计[L,H]区间上正约数最多的那个数P(如有多个,取最小值)以及P的正约数的个数D. 2.原理: 对于任意的一 ...

  2. BZOJ 3597 SCOI2014 方伯伯送椰子 网络流分析+SPFA

    原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3597 Description 四川的方伯伯为了致富,决定引进海南的椰子树.方伯伯的椰子园十 ...

  3. ajax中用jsonp接收json数据

    最近在做查快递网页时遇到一个问题,调用的快递100的api,但是快递100api不允许跨域请求,就是用127.0.0.1发的请求会直接被拦截. 只是个简单的网页,不想自己做服务器转发,最后找到了一个y ...

  4. python进制转换(二进制、十进制和十六进制)及注意事项

    使用内置函数实现进制转换实现比较简单,主要用到以下函数: bin().oct().int().hex() 下面分别详解一下各个函数的使用(附实例) 第一部分:其他进制转十进制 1.二进制转十进制 使用 ...

  5. EasyUI 显示表单数据 小记

    界面图:

  6. unity 归纳

    1.获取控件四个角在屏幕上的坐标 Vector3[] corners = new Vector3[]; gameObject.GetComponent<RectTransform>().G ...

  7. element-ui的el-tabel组件怎么使用type=“expand”实现表格嵌套并且在子表格没有数据的时候隐藏展开按钮

    效果如下: 试过很多种办法,思路都在怎么控制<el-table-column type="expand">里面的type上,比如使用v-show等等,但是发现,要不就是 ...

  8. Div+Css制作圆

    Div+Css制作四分之一圆主要是使用Css3.0中的border-radius这个圆角隐藏属性.利用这一属性,我们可以画圆,画半圆,四分之三圆,四分之一圆等.以后我会更新…… 如何使用border- ...

  9. Flash by sshockwave [树dp]

    题目 给定一棵树,每个点有一个活动时间,长度为正整数$t_i$ 你需要安排每个点的活动时间什么时候开始什么时候结束,并且满足:任何一个时刻没有两个相邻的点都在活动 开始时刻为0,在以上条件下最小化所有 ...

  10. 算法学习——kruskal重构树

    kruskal重构树是一个比较冷门的数据结构. 其实可以看做一种最小生成树的表现形式. 在普通的kruskal中,如果一条边连接了在2个不同集合中的点的话,我们将合并这2个点所在集合. 而在krusk ...