Android 5.0源码分析---startService与bindService的区别
来源:互联网 发布:学习软件 编辑:程序博客网 时间:2024/06/05 07:33
startService启动过程简述
- 主进程调用到ActivityManagerService进程中,完成新进程的创建;
这一步主要是解析Intent中的参数,解析前面在AndroidManifest.xml定义的Service标签的intent-filter相关内容。紧接着启动一个新的进程。 - 在新的进程启动完成后,从新进程调用到ActivityManagerService进程中,获取要在新进程启动的服务的相关信息;
在此准备好了一个ServiceRecord记录Service中的信息,以及一个ProcessRecord记录了新进程的信息,当我们准备好这些参数后就要回到进程中真正启动Service了。 - 从ActivityManagerService进程又回到新进程中,最终将服务启动起来;
加载这个class的类,调用其中的OnCreate方法将Service启动起来。
bindService启动过程的区别
与startService一样我们都会启动一个Service 调用它的OnCreate方法,但是在这之后我们还需要调用
ActivityManagerService.requestServiceBindingsLocked函数,这个调用是用来执行CounterService的onBind函数的。
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i, boolean execInFg, boolean rebind) { if (r.app == null || r.app.thread == null) { // If service is not currently running, can't yet bind. return false; } if ((!i.requested || rebind) && i.apps.size() > 0) { try { bumpServiceExecutingLocked(r, execInFg, "bind"); r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.repProcState); if (!rebind) { i.requested = true; } i.hasBound = true; i.doRebind = false; } catch (RemoteException e) { if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r); return false; } } return true; }
这里的ServiceRecord 就是先前我们创建的Service 的记录,我们可以看到在函数中我们调用了scheduleBindService:
public final void scheduleBindService(IBinder token, Intent intent, boolean rebind, int processState) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(token); intent.writeToParcel(data, 0); data.writeInt(rebind ? 1 : 0); data.writeInt(processState); mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); }
最终进程间通信完成后会调用到的是:
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) { final long origId = Binder.clearCallingIdentity(); try { if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r + " " + intent + ": " + service); if (r != null) { Intent.FilterComparison filter = new Intent.FilterComparison(intent); IntentBindRecord b = r.bindings.get(filter); if (b != null && !b.received) { b.binder = service; b.requested = true; b.received = true; for (int conni=r.connections.size()-1; conni>=0; conni--) { ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni); for (int i=0; i<clist.size(); i++) { ConnectionRecord c = clist.get(i); if (!filter.equals(c.binding.intent.intent)) { if (DEBUG_SERVICE) Slog.v( TAG, "Not publishing to: " + c); if (DEBUG_SERVICE) Slog.v( TAG, "Bound intent: " + c.binding.intent.intent); if (DEBUG_SERVICE) Slog.v( TAG, "Published intent: " + intent); continue; } if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c); try { c.conn.connected(r.name, service); } catch (Exception e) { Slog.w(TAG, "Failure sending service " + r.name + " to connection " + c.conn.asBinder() + " (in " + c.binding.client.processName + ")", e); } } } } serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false); } } finally { Binder.restoreCallingIdentity(origId); } }
这里传进来的参数token是一个ServiceRecord对象,它是在上面的Step 6中创建的,代表CounterService这个Service。我们曾经把一个ConnectionRecord放在ServiceRecord.connections列表中,现在我们需要把它取出来 每一个ConnectionRecord里面都有一个成员变量conn,它的类型是IServiceConnection,是一个Binder对象的远程接口,这个Binder对象又是什么呢?这就是我们在中创建的LoadedApk.ServiceDispatcher.InnerConnection对象了。因此,这里执行c.conn.connected函数后就会进入到LoadedApk.ServiceDispatcher.InnerConnection.connected函数中去了。
最终函数会调用到InnerConnection 中的connected:
public void connected(ComponentName name, IBinder service) throws RemoteException { LoadedApk.ServiceDispatcher sd = mDispatcher.get(); if (sd != null) { sd.connected(name, service); } }
再次跟进:
public void connected(ComponentName name, IBinder service) { if (mActivityThread != null) { mActivityThread.post(new RunConnection(name, service, 0)); } else { doConnected(name, service); } }
我们之前传入一个获取服务方的一个handler,这里会将这个binder发给线程
- Android 5.0源码分析---startService与bindService的区别
- 源码分析Android bindService与startService区别
- android startService 与bindService的区别
- android service startService与bindService的区别
- Android之startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService 与 bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- git 的一些常用命令整理
- 【salesforce】Apexcodeで選択リスト型の値を取る
- CentOS-6.3安装配置JDK-7或 JDK-6
- android悬浮窗口的实现
- 函数申明对函数模板实例化的屏蔽
- Android 5.0源码分析---startService与bindService的区别
- android 按home键完全退出app的问题
- 14:05:15,181 ERROR PARSER:56 - <AST>:0:0: unexpected end of subtree
- Apache Kafka监控之Kafka Web Console
- windows 程序如何通过命令行方式输入参数启动
- 基本算法题汇
- IOS Socket使用大全
- Eclipse SVN E200007: Commit failed (details follow) 解决方法
- 设置颜色多变的文本