技术改变世界 阅读塑造人生! - shaogx.com

This string was altered by TechBlog\Plugins\Example.; This is an example to show the potential of an offcanvas layout pattern in Bootstrap. Try some responsive-range viewport sizes to see it in action.

Android进程间通信

一、概念及说明Android为了屏蔽进程的概念,利用不同的组件[Activity、Service]来表示进程之间的通信!组件间通信的核心机制是Intent,通过Intent可以开启一个Activity或Service,不论这个Activity或Service是属于当前应用还是其它应用的!                                                                                本文如有bug,请指出啊!!大家一同进步!!                                                             谢谢!!Intent包含两部分:1、目的[action]--要往哪里去2、内容[category、data]--路上带了些啥,区分性数据或内容性数据Intent类型:1、显式--直接指定消息目的地,只适合同一进程内的不同组件之间通信new Intent(this,Target.class)2、隐式--AndroidMainifest.xml中注册,一般用于跨进程通信new Intent(String action) 二、实现-Intent简单进程间通信显式的Intent较为简单! 如何实现隐式Intent呢?在AndroidManifest.xml文件中定义<activity>说明:1、一个<activity>包括:零个或多个<intent-filter>它主要是作为匹配的标准,能否匹配成功由<action>、<category>、<data>三个tag共同决定的。 2、一个<intent-filter>包括:一个或多个 <action>零个或多个 <category>  指定<activity>的分类特征eg:<category android:name="android.intent.category.LAUNCHER" /> --说明该<activity>是该project运行的第一个界面<category android:name="android.intent.category.HOME" /> --说明该<activity>可以作为Launcher的,即系统操作界面<category android:name="android.intent.category.DEFAULT" /> --缺省情况零个或一个 <data>-- 指定携带的数据的类型,使用MIME类型描述方式来描述eg:<data android:mimeType="video/mpeg" />video/mpeg表示编码格式为mpeg的视频,也可以使用通配符video/*表示任意格式的视频文件类型; 在查询ContentProvider时,可以使用<data android:mimeType="vnd.android.cursor.dir/vnd.myq.note" />查询上来的数据是多个记录<data android:mimeType="vnd.android.cursor.item/vnd.myq.note" />查询上来的数据是单个记录如上设置,要重写SQLiteOpenHelper的getType(Uri uri)方法eg: @Override public String getType(Uri uri) {  final int match = sUriMatcher.match(uri) ;  switch(match)  {  case NOTES :  case LIVE_FOLDER_NOTES:   return "vnd.android.cursor.dir/vnd.myq.note" ;     case NOTES_ID :   return "vnd.android.cursor.item/vnd.myq.note" ;     default:   throw new IllegalArgumentException("invalid uri : " + uri) ;  } } 数据的URI由scheme(协议),host,port,path四部分:scheme://host:port/path<data android:scheme="http://localhost:8080/test.jsp" />3、一个Intent对应多种匹配结果的处理说明 一个intent有多个可匹配的处理组件,系统如何处理?分响应消息的组件类型:1)如果是service那么这些service都可以启动并处理消息。2)如果是Activity则会弹出一个对话框让用户进行选择。 4、安全性问题 如果不同进程间的组件可以通过隐式消息互相通信,那程序不是可以轻易调用到其他的程序或者系统中的一些敏感程序的组件,这样会不会很不安全呢?其实Android在安全方面有一个统一,完备和轻便的安全策略模型。简单一点说就是:权限设置问题我们可以自己定义permission,然后在需要的组件处设置该permission,那么用户要想该组件,必须要配置该permission,否则访问失败的!eg:1、定义permission<permission-group android:name="android.permission-group.MYQ_INFO"/> <permission     android:name="com.myq.android.permission.DATETIME_SERVICE"     android:permissi     android:protecti     /> 2、配置permission<service android:name=".DateTimeService" android:permission="com.myq.android.permission.DATETIME_SERVICE">   <intent-filter> <action android:name="com.myq.android.MultiProcessTest.DATETIMESERVICE_ACTION" />   </intent-filter></service> 3、使用permission<uses-permission android:name="com.myq.android.permission.DATETIME_SERVICE"/> 三、IPC机制有了Intent这种基于消息的进程内或进程间通信模型,我们就可以通过Intent去开启一个Service,可以通过Intent跳转到另一个Activity,不论上面的Service或Activity是在当前进程还是其它进程内即不论是当前应用还是其它应用的Service或Activity,通过消息机制都可以进行通信!但是通过消息机制实现的进程间通信,有一个弊端就是,如果我们的Activity与Service之间的交往不是简单的Activity开启Service操作,而是要随时发一些控制请求,那么必须就要保证Activity在Service的运行过程中随时可以连接到Service。eg:音乐播放程序后台的播放服务往往独立运行,以方便在使用其他程序界面时也能听到音乐。同时这个后台播放服务也会定义一个控制接口,比如播放,暂停,快进等方法,任何时候播放程序的界面都可以连接到播放服务,然后通过这组控制接口方法对其控制。 如上的需求仅仅通过Intent去开启Service就无法满足了!从而Android的显得稍微笨重的IPC机制就出现了,然而它的出现只适用于Activity与Service之间的通信,类似于远程方法调用,就像是C/S模式的访问,通过定义AIDL接口文件来定义一个IPC接口,Server端实现IPC接口,Client端调用IPC接口的本地代理。由于IPC调用是同步的,如果一个IPC服务需要超过几毫秒的时间才能完成的话,你应该避免在Activity的主线程中调用,否则IPC调用会挂起应用程序导致界面失去响应。在 这种情况下,应该考虑单起一个线程来处理IPC访问。两个进程间IPC看起来就象是一个进程进入另一个进程执行代码然后带着执行的结果返回。IPC机制鼓励我们“尽量利用已有功能,利用IPC和包含已有功能的程序协作完成一个完整的项目” IPC实现demo:我的project -- MultiProcessTestpackage -- com.myq.android.MultiProcessTest 1、AIDL文件,我是放在package下,文件名称为:IDateTimeService.aidl文件内容为:package com.myq.android.MultiProcessTest ;interface IDateTimeService { String getCurrentDateTime(in String format) ;} 如果正确配置,会在gen下,生成同名的java文件简单摘要://我们需要实现的类Stubpublic interface IDateTimeService extends android.os.IInterface{...public static abstract class Stubextends android.os.Binder implements com.myq.android.MultiProcessTest.IDateTimeService{ ...//获取实例的方法asInterfacepublic static com.myq.android.MultiProcessTest.IDateTimeService asInterface(android.os.IBinder obj){  ...} ...}//我们自己的业务方法,需要实现的public java.lang.String getCurrentDateTime(java.lang.String format) throws android.os.RemoteException;} 2、Service中实现IDateTimeService.Stubeg:package com.myq.android.MultiProcessTest;import java.text.SimpleDateFormat;import java.util.Date;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.util.Log; public class DateTimeService extends Service {  public static final String DATETIME_SERVICE_ACTION = "com.myq.android.MultiProcessTest.DATETIMESERVICE_ACTION" ;  private static final String TAG = "--------DateTimeService-------" ;  private  SimpleDateFormat sdf ;  private final IDateTimeService.Stub stub = new IDateTimeService.Stub() {    public String getCurrentDateTime(String format) throws RemoteException {   return getCurrentDateTimeString(format) ;  } } ;  private synchronized String getCurrentDateTimeString(String format) {     sdf = new SimpleDateFormat(format) ;     final String temp = sdf.format(new Date()) ;   Log.i(TAG,"getCurrentDateTimeString--" + Thread.currentThread() + "--" + temp) ;   return temp ; }  public IBinder onBind(Intent arg0)  {  Log.i(TAG, "onBind--" + Thread.currentThread()) ;  return stub; }}3、Client端代码实现private ServiceConnection mServiceConn = new ServiceConnection() {    public void onServiceConnected(ComponentName name, IBinder service) {   mDateTimeService = IDateTimeService.Stub.asInterface(service) ;  }    public void onServiceDisconnected(ComponentName name) {   mDateTimeService = null ;  } } ; 说明:网上的好多资料都没有涉及IPC调用的AIDL的具体说明!它本质上是Server端和Client端都具有相同的AIDL文件,要位于相同的包下,即package的包名药一样,然后才能正确的通过proxy访问,否则client与server的aidl文件处于不同package会出错的。 aidl模型如下:                |<--------------------aidl---------------------->| client端-->proxy  ----------parcel数据包-------- stub<---server端从而proxy+parcel+stub构成了aidl.只不过,proxy运行在客户进程,而stub运行在服务端进程。当你通过aidl去访问服务端时,客户端会阻塞在proxy,服务端处理完后,通知proxy返回。 四、附件及说明1、附件是我测试所用的demo,我用的系统是ubuntu9,Android2.2版本基本功能:可以根据用户选择的不同输出格式输出当前系统的时间。2、运行顺序:先运行Server端:MultiProcessTest再运行Client端:MultiProcessTestClient 3、注意点:Server和Client端的AIDL文件必须要位于同package下,否则会出错安全性问题实现,权限控制--定义、配置、使用异步处理问题--Handler  本文出自 “苗运齐的博客” 博客,请务必保留此出处http://myqdroid.blog.51cto.com/2057579/394189... 全文

Android进程间通信 Android AIDL实现 Android IPC机制 Android AIDL Android IPC

android跨进程通信(IPC):使用AIDL

AIDL的作用AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。 AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。选择AIDL的使用场合官方文档特别提醒我们何时使用AIDL是必要的:只有你允许客户端从不同的应用程序为了进程间的通信而去访问你的service,以及想在你的service处理多线程。如果不需要进行不同应用程序间的并发通信(IPC),you should create your interface by implementing a Binder;或者你想进行IPC,但不需要处理多线程的,则implement your interface using a Messenger。无论如何,在使用AIDL前,必须要理解如何绑定service——bindService。如何绑定服务,请参考我的另一篇文章:http://blog.csdn.net/singwhatiwanna/article/details/9058143。这里先假设你已经了解如何使用bindService。如何使用AIDL1.先建立一个android工程,用作服务端创建一个android工程,用来充当跨进程通信的服务端。2.创建一个包名用来存放aidl文件创建一个包名用来存放aidl文件,比如com.ryg.sayhi.aidl,在里面新建IMyService.aidl文件,如果需要访问自定义对象,还需要建立对象的aidl文件,这里我们由于使用了自定义对象Student,所以,还需要创建Student.aidl和Student.java。注意,这三个文件,需要都放在com.ryg.sayhi.aidl包里。下面描述如何写这三个文件。IMyService.aidl代码如下:package com.ryg.sayhi.aidl; import com.ryg.sayhi.aidl.Student; interface IMyService { List<Student> getStudent(); void addStudent(in Student student); }说明:aidl中支持的参数类型为:基本类型(int,long,char,boolean等),String,CharSequence,List,Map,其他类型必须使用import导入,即使它们可能在同一个包里,比如上面的Student,尽管它和IMyService在同一个包中,但是还是需要显示的import进来。 另外,接口中的参数除了aidl支持的类型,其他类型必须标识其方向:到底是输入还是输出抑或两者兼之,用in,out或者inout来表示,上面的代码我们用in标记,因为它是输入型参数。在gen下面可以看到,eclipse为我们自动生成了一个代理类public static abstract class Stub extends android.os.Binder implements com.ryg.sayhi.aidl.IMyService可见这个Stub类就是一个普通的Binder,只不过它实现了我们定义的aidl接口。它还有一个静态方法public static com.ryg.sayhi.aidl.IMyService asInterface(android.os.IBinder obj)这个方法很有用,通过它,我们就可以在客户端中得到IMyService的实例,进而通过实例来调用其方法。Student.aidl代码如下:package com.ryg.sayhi.aidl; parcelable Student;说明:这里parcelable是个类型,首字母是小写的,和Parcelable接口不是一个东西,要注意。Student.java代码如下:package com.ryg.sayhi.aidl; import java.util.Locale; import android.os.Parcel; import android.os.Parcelable; public final class Student implements Parcelable { public static final int SEX_MALE = 1; public static final int SEX_FEMALE = 2; public int sno; public String name; public int sex; public int age; public Student() { } public static final Parcelable.Creator<Student> CREATOR = new Parcelable.Creator<Student>() { public Student createFromParcel(Parcel in) { return new Student(in); } public Student[] newArray(int size) { return new Student[size]; } }; private Student(Parcel in) { readFromParcel(in); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(sno); dest.writeString(name); dest.writeInt(sex); dest.writeInt(age); } public void readFromParcel(Parcel in) { sno = in.readInt(); name = in.readString(); sex = in.readInt(); age = in.readInt(); } @Override public String toString() { return String.format(Locale.ENGLISH, "Student[ %d, %s, %d, %d ]", sno, name, sex, age); } }说明:通过AIDL传输非基本类型的对象,被传输的对象需要序列化,序列化功能java有提供,但是android sdk提供了更轻量级更方便的方法,即实现Parcelable接口,关于android的序列化,我会在以后写文章介绍。这里只要简单理解一下就行,大意是要实现如下函数 readFromParcel : 从parcel中读取对象writeToParcel :将对象写入parceldescribeContents:返回0即可Parcelable.Creator<Student> CREATOR:这个照着上面的代码抄就可以需要注意的是,readFromParcel和writeToParcel操作数据成员的顺序要一致3.创建服务端service创建一个service,比如名为MyService.java,代码如下:/** * @author scott */ public class MyService extends Service { private final static String TAG = "MyService"; private static final String PACKAGE_SAYHI = "com.example.test"; private NotificationManager mNotificationManager; private boolean mCanRun = true; private List<Student> mStudents = new ArrayList<Student>(); //这里实现了aidl中的抽象函数 private final IMyService.Stub mBinder = new IMyService.Stub() { @Override public List<Student> getStudent() throws RemoteException { synchronized (mStudents) { return mStudents; } } @Override public void addStudent(Student student) throws RemoteException { synchronized (mStudents) { if (!mStudents.contains(student)) { mStudents.add(student); } } } //在这里可以做权限认证,return false意味着客户端的调用就会失败,比如下面,只允许包名为com.example.test的客户端通过, //其他apk将无法完成调用过程 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { String packageName = null; String[] packages = MyService.this.getPackageManager(). getPackagesForUid(getCallingUid()); if (packages != null && packages.length > 0) { packageName = packages[0]; } Log.d(TAG, "onTransact: " + packageName); if (!PACKAGE_SAYHI.equals(packageName)) { return false; } return super.onTransact(code, data, reply, flags); } }; @Override public void onCreate() { Thread thr = new Thread(null, new ServiceWorker(), "BackgroundService"); thr.start(); synchronized (mStudents) { for (int i = 1; i < 6; i++) { Student student = new Student(); student.name = "student#" + i; student.age = i * 5; mStudents.add(student); } } mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); super.onCreate(); } @Override public IBinder onBind(Intent intent) { Log.d(TAG, String.format("on bind,intent = %s", intent.toString())); displayNotificationMessage("服务已启动"); return mBinder; } @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { mCanRun = false; super.onDestroy(); } private void displayNotificationMessage(String message) { Notification notification = new Notification(R.drawable.icon, message, System.currentTimeMillis()); notification.flags = Notification.FLAG_AUTO_CANCEL; notification.defaults |= Notification.DEFAULT_ALL; PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MyActivity.class), 0); notification.setLatestEventInfo(this, "我的通知", message, contentIntent); mNotificationManager.notify(R.id.app_notification_id + 1, notification); } class ServiceWorker implements Runnable { long counter = 0; @Override public void run() { // do background processing here..... while (mCanRun) { Log.d("scott", "" + counter); counter++; try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }说明:为了表示service的确在活着,我通过打log的方式,每2s打印一次计数。上述代码的关键在于onBind函数,当客户端bind上来的时候,将IMyService.Stub mBinder返回给客户端,这个mBinder是aidl的存根,其实现了之前定义的aidl接口中的抽象函数。问题:问题来了,有可能你的service只想让某个特定的apk使用,而不是所有apk都能使用,这个时候,你需要重写Stub中的onTransact方法,根据调用者的uid来获得其信息,然后做权限认证,如果返回true,则调用成功,否则调用会失败。对于其他apk,你只要在onTransact中返回false就可以让其无法调用IMyService中的方法,这样就可以解决这个问题了。4. 在AndroidMenifest中声明service <service android:name="com.ryg.sayhi.MyService" android:process=":remote" android:exported="true" > <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <action android:name="com.ryg.sayhi.MyService" /> </intent-filter> </service>说明:上述的 <action android:name="com.ryg.sayhi.MyService" />是为了能让其他apk隐式bindService,通过隐式调用的方式来起activity或者service,需要把category设为default,这是因为,隐式调用的时候,intent中的category默认会被设置为default。5. 新建一个工程,充当客户端新建一个客户端工程,将服务端工程中的com.ryg.sayhi.aidl包整个拷贝到客户端工程的src下,这个时候,客户端com.ryg.sayhi.aidl包是和服务端工程完全一样的。如果客户端工程中不采用服务端的包名,客户端将无法正常工作,比如你把客户端中com.ryg.sayhi.aidl改一下名字,你运行程序的时候将会crash,也就是说,客户端存放aidl文件的包必须和服务端一样。客户端bindService的代码就比较简单了,如下:import com.ryg.sayhi.aidl.IMyService; import com.ryg.sayhi.aidl.Student; public class MainActivity extends Activity implements OnClickListener { private static final String ACTION_BIND_SERVICE = "com.ryg.sayhi.MyService"; private IMyService mIMyService; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mIMyService = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { //通过服务端onBind方法返回的binder对象得到IMyService的实例,得到实例就可以调用它的方法了 mIMyService = IMyService.Stub.asInterface(service); try { Student student = mIMyService.getStudent().get(0); showDialog(student.toString()); } catch (RemoteException e) { e.printStackTrace(); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button1 = (Button) findViewById(R.id.button1); button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { if (view.getId() == R.id.button1) { Intent intentService = new Intent(ACTION_BIND_SERVICE); intentService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); MainActivity.this.bindService(intentService, mServiceConnection, BIND_AUTO_CREATE); } } public void showDialog(String message) { new AlertDialog.Builder(MainActivity.this) .setTitle("scott") .setMessage(message) .setPositiveButton("确定", null) .show(); } @Override protected void onDestroy() { if (mIMyService != null) { unbindService(mServiceConnection); } super.onDestroy(); } }运行效果可以看到,当点击按钮1的时候,客户端bindService到服务端apk,并且调用服务端的接口mIMyService.getStudent()来获取学生列表,并且把返回列表中第一个学生的信息显示出来,这就是整个ipc过程,需要注意的是:学生列表是另一个apk中的数据,通过aidl,我们才得到的。另外,如果你在onTransact中返回false,将会发现,获取的学生列表是空的,这意味着方法调用失败了,也就是实现了权限认证。... 全文

ipc aidl 进程间通信 service 服务

Android Bound Service(一)

ref:http://developer.android.com/guide/components/bound-services.html‏前言 重新学习这一项技术,主要的原因,是因为以前没有好好的学,那时总觉得作品能动,能完成工作就好了,而这种得过且过的想法,大大地影响了我的技术程度,也因此,在这个这个博客里,有许多的复习心得。有幸得到一位前辈的指导,指出,若只是学习,而无实际应用,这样进步会较少,因此,最好要多看源码,并且自己多尝试多实践,这样学习一万小时,应该能有小进步,因此开始了 Bound Service相关学习/复习工作。... 全文

android ipc 跨进程通讯 基础

Android调用C程序的七荤八素

  在安卓平台上开发应用,通用的语言是 Java ,而对于从其它平台迁移到安卓的项目、产品,或者对于惯用 C/C++ 编程的开发人员来讲,会希望复用已有的 C/C++ 代码。安卓平台提供了复用 Native 代码的途径,也提供了编译 C 代码的环境和工具链: NDK 。 NDK 是一套工具链,有了它,在安卓上使用 C 语言成为可能。其实安卓原本是在 Linux 上套了个 Java 环境,要说不能用C 那才是不可思议的事儿,只是 Google 没完全开放而已(话说我到现在都在腹黑,为么不能让 C 程序员在安卓上活得自在些呢,简直是人为制造障碍)。  安卓平台上服用 C 代码有两种方式:JNI原生 C 可执行程序... 全文

android C IPC BINDER

2011年Android IPC进程间通讯机制学习笔记之一

2011年Android IPC进程间通讯机制学习笔记之一一.Linux系统进程间通信有哪些方式?1.socket;2.name pipe命名管道;3.message queue消息队列;4.singal信号量;5.share memory共享内存;二.Java系统的通信方式是什么?1.socket;2.name pipe;三.Android系统通信方式是什么?Binder 通信;四.Binder通信的优势是什么?高效率五.Binder通信的特点是什么?是同步,而不是异步;六.Binder通信是如何实现的?1.Binder通信是通过linux的binder driver来实现的,2.Binder通信操作类似线程迁移(thread migration),两个进程间IPC看起来就象是一个进程进入另一个进程执行代码然后带着执行的结果返回;3.Binder的用户空间为每一个进程维护着一个可用的线程池,线程池用于处理到来的IPC以及执行进程本地消息,Binder通信是同步而不是异步。七. Android中的 Binder通信实现要点:1. Android中的Binder通信是基于Service与Client的工作模型的;2. 所有需要IBinder通信的进程都必须创建一个IBinder接口;3. 系统中有一个进程管理所有的system service:4. Android不允许用户添加非授权的System service;5. 现在源码开放了,我们可以修改一些代码来实现添加底层system Service的目的;6. 对用户程序来说,我们也要创建server,或者Service用于进程间通信;7. ActivityManagerService管理JAVA应用层所有的service创建与连接(connect),disconnect;8. 所有的Activity也是通过这个service来启动,加载的;9. ActivityManagerService也是加载在Systems Servcie中的;八.Android的 Service工作流程1.Android虚拟机启动之前系统会先启动service Manager进程;2.service Manager打开binder驱动,并通知binder kernel驱动程序这个进程将作为System Service Manager;3.然后该进程将进入一个循环,等待处理来自其他进程的数据。4.用户创建一个System service后,通过defaultServiceManager得到一个远程ServiceManager的接口,通过这个接口我们可以调用addService函数将System service添加到Service Manager进程中;5.然后client可以通过getService获取到需要连接的目的Service的IBinder对象,这个IBinder是Service的BBinder在binder kernel的一个参考,6.所以service IBinder 在binder kernel中不会存在相同的两个IBinder对象,每一个Client进程同样需要打开Binder驱动程序。对用户程序而言,我们获得这个对象就可以通过binder kernel访问service对象中的方法。7.Client与Service在不同的进程中,通过这种方式实现了类似线程间的迁移的通信方式,对用户程序而言当调用Service返回的IBinder接口后,访问Service中的方法就如同调用自己的函数。... 全文

android 通讯 service manager system migration

Android进程间通信(IPC)机制Binder简要介绍和学习计划

        在Android系统中,每一个应用程序都是由一些Activity和Service组成的,这些Activity和Service有可能运行在同一个进程中,也有可能运行在不同的进程中。那么,不在同一个进程的Activity或者Service是如何通信的呢?这就是本文中要介绍的Binder进程间通信机制了。本博参加博客之星评选,求投票:点击投票... 全文

android linux内核 manager server service

浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路

        上一篇文章Android进程间通信(IPC)机制Binder简要介绍和学习计划简要介绍了Android系统进程间通信机制Binder的总体架构,它由Client、Server、Service Manager和驱动程序Binder四个组件构成。本文着重介绍组件Service Manager,它是整个Binder机制的守护进程,用来管理开发者创建的各种Server,并且向Client提供查询Server远程接口的功能。本博参加博客之星评选,求投票:点击投票... 全文

android manager service struct thread

1