- 浏览: 4154064 次
文章分类
最新评论
-
klxh:
Android如何一次安装多个apk -
kchiu:
废话啊啊啊
TCP,socket 心跳检测 -
追求幸福:
iOS: 当发生signal 9为 kill的时候,程序直接被 ...
android和iOS平台的崩溃捕获和收集 -
andsy2008:
给的地址,没豆子呢,能单独发一份给我吗,andsy2008@1 ...
点餐订餐系统应用android源码 -
王粤新:
[b][i][u]引用[list]
[*][flash=200 ...
百度地图SDK for Android【事件监听】
Android系统在新进程中启动自定义服务过程(startService)的原理分析
在编写Android应用程序时,我们一般将一些计算型的逻辑放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通过startService函数来启动这个服务。在本文中,将详细分析主进程是如何通过startService函数来在新进程中启动自定义服务的。
在主进程调用startService函数时,会通过Binder进程间通信机制来通知ActivitManagerService来创建新进程,并且启动指定的服务。在Android系统中,Binder进程间通信机制使用非常广泛,因此,希望读者在继续阅读下面的内容之前,对Android系统和Binder进程间通信机制有一定的了解,具体可以参考前面Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。
关于startService的具体用法,可以参考前面Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划一文中用到的实例,它是Activity类的一个成员函数:
package shy.luo.ashmem; ...... public class Client extends Activity implements OnClickListener { ...... IMemoryService memoryService = null; ...... @Override public void onCreate(Bundle savedInstanceState) { ...... IMemoryService ms = getMemoryService(); if(ms == null) { startService(new Intent("shy.luo.ashmem.server")); } else { Log.i(LOG_TAG, "Memory Service has started."); } ...... Log.i(LOG_TAG, "Client Activity Created."); } ...... }
这里的“shy.luo.ashmem.server”是在程序配置文件AndroidManifest.xml配置的Service的名字,用来告诉Android系统它所要启动的服务的名字:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="shy.luo.ashmem" android:sharedUserId="android.uid.system" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> ...... <service android:enabled="true" android:name=".Server" android:process=".Server" > <intent-filter> <action android:name="shy.luo.ashmem.server"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </service> </application> </manifest>这里,名字“shy.luo.ashmem.server”对应的服务类为shy.luo.ashmem.Server,下面语句:
startService(new Intent("shy.luo.ashmem.server"));就表示要在一个新的进程中启动shy.luo.ashmem.Server这个服务类,它必须继承于Android平台提供的Service类:
package shy.luo.ashmem; ...... public class Server extends Service { ...... @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { ...... } ...... }下面,我们来看看Activity类中的startService成员函数是如何实现的。
先来看看Activity的类图:
从图中可以看出,Activity继承了ContextWrapper类,而在ContextWrapper类中,实现了startService函数。在ContextWrapper类中,有一个成员变量mBase,它是一个ContextImpl实例,而ContextImpl类和ContextWrapper类一样继承于Context类,ContextWrapper类的startService函数最终过调用ContextImpl类的startService函数来实现。这种类设计方法在设计模式里面,就称之为装饰模式(Decorator),或者包装模式(Wrapper)。
在ContextImpl类的startService类,最终又调用了ActivityManagerProxy类的startService来实现启动服务的操作,看到这里的Proxy关键字,回忆一下前面Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析这篇文章,就会知道ActivityManagerProxy是一个Binder对象的远程接口了,而这个Binder对象就是我们前面所说的ActivityManagerService了。
这个ActivityManagerService类实现在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中,它是Binder进程间通信机制中的Server角色,它是随机启动的。随机启动的Server是在frameworks/base/services/java/com/android/server/SystemServer.java文件里面进行启动的,我们来看一下ActivityManagerService启动相关的代码:
class ServerThread extends Thread { ...... @Override public void run() { ...... // Critical services... try { ...... context = ActivityManagerService.main(factoryTest); ...... ActivityManagerService.setSystemProcess(); ...... } catch (RuntimeException e) { Slog.e("System", "Failure starting core service", e); } ...... } ...... }首先是调用ActivityManagerService.main函数来创建一个ActivityManagerService实例,然后通过调用ActivityManagerService.setSystemProcess函数把这个Binder实例添加Binder进程间通信机制的守护进程ServiceManager中去:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... static ActivityManagerService mSelf; ...... public static void setSystemProcess() { try { ActivityManagerService m = mSelf; ServiceManager.addService("activity", m); ...... } catch (PackageManager.NameNotFoundException e) { ...... } } ...... public static final Context main(int factoryTest) { ...... ActivityManagerService m = thr.mService; mSelf = m; ...... } }这样,ActivityManagerService就启动起来了。
回到ActivityManagerProxy类的startService函数中,它定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
class ActivityManagerProxy implements IActivityManager { ...... public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); service.writeToParcel(data, 0); data.writeString(resolvedType); mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0); reply.readException(); ComponentName res = ComponentName.readFromParcel(reply); data.recycle(); reply.recycle(); return res; } ...... }参数service是一个Intent实例,它里面指定了要启动的服务的名称,就是前面我们所说的“shy.luo.ashmem.server”了。
参数caller是一个IApplicationThread实例,它是一个在主进程创建的一个Binder对象。在Android应用程序中,每一个进程都用一个ActivityThread实例来表示,而在ActivityThread类中,有一个成员变量mAppThread,它是一个ApplicationThread实例,实现了IApplicationThread接口,它的作用是用来辅助ActivityThread类来执行一些操作,这个我们在后面会看到它是如何用来启动服务的。
参数resolvedType是一个字符串,它表示service这个Intent的MIME类型,它是在解析Intent时用到的。在这个例子中,我们没有指定这个Intent 的MIME类型,因此,这个参数为null。
ActivityManagerProxy类的startService函数把这三个参数写入到data本地变量去,接着通过mRemote.transact函数进入到Binder驱动程序,然后Binder驱动程序唤醒正在等待Client请求的ActivityManagerService进程,最后进入到ActivityManagerService的startService函数中。
ActivityManagerService的startService函数的处理流程如下图所示:
在这个序列图中,一共有20个步骤,下面说明每一步。
Step 1. ActivityManagerService.startService
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType) { // Refuse possible leaked file descriptors if (service != null && service.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); } synchronized(this) { final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res = startServiceLocked(caller, service, resolvedType, callingPid, callingUid); Binder.restoreCallingIdentity(origId); return res; } } ...... }这里的参数caller、service和resolvedType分别对应ActivityManagerProxy.startService传进来的三个参数。
Step 2.ActivityManagerService.startServiceLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid) { synchronized(this) { ...... ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPid, callingUid); ...... ServiceRecord r = res.record; ...... if (!bringUpServiceLocked(r, service.getFlags(), false)) { return new ComponentName("!", "Service process is bad"); } return r.name; } } ...... }函数首先通过retrieveServiceLocked来解析service这个Intent,就是解析前面我们在AndroidManifest.xml定义的Service标签的intent-filter相关内容,然后将解析结果放在res.record中,然后继续调用bringUpServiceLocked进一步处理。
Step 3. ActivityManagerService.bringUpServiceLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... private final boolean bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean whileRestarting) { ...... final String appName = r.processName; ...... // Not running -- get it started, and enqueue this service record // to be executed when the app comes up. if (startProcessLocked(appName, r.appInfo, true, intentFlags, "service", r.name, false) == null) { ...... return false; } if (!mPendingServices.contains(r)) { mPendingServices.add(r); } return true; } ...... }这里的appName便是我们前面在AndroidManifest.xml文件定义service标签时指定的android:process属性值了,即“.Server”。
接着调用startProcessLocked函数来创建一个新的进程,以便加载自定义的Service类。最后将这个ServiceRecord保存在成员变量mPendingServices列表中,后面会用到。
Step 4.ActivityManagerService.startProcessLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) { ...... try { ...... int pid = Process.start("android.app.ActivityThread", mSimpleProcessManagement ? app.processName : null, uid, uid, gids, debugFlags, null); ...... if (pid == 0 || pid == MY_PID) { ...... } else if (pid > 0) { app.pid = pid; app.removed = false; synchronized (mPidsSelfLocked) { this.mPidsSelfLocked.put(pid, app); ...... } } else { ...... } } catch (RuntimeException e) { ...... } } ...... }这里调用Process.start函数创建了一个新的进程,指定新的进程执行android.app.ActivityThread类。最后将表示这个新进程的ProcessRecord保存在mPidSelfLocked列表中,后面会用到。
Step 5. Process.start
这个函数定义在frameworks/base/core/java/android/os/Process.java文件中,这个函数我们就不看了,有兴趣的读者可以自己研究一下。在这个场景中,它就是新建一个进程,然后导入android.app.ActivityThread这个类,然后执行它的main函数。
Step 6.ActivityThread.main
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
public final class ActivityThread { ...... public static final void main(String[] args) { ...... Looper.prepareMainLooper(); ...... ActivityThread thread = new ActivityThread(); thread.attach(false); ...... Looper.loop(); ...... thread.detach(); ...... } }注意,执行到这里的时候,已经是在上一步创建的新进程里面了,即这里的进程是用来启动服务的,原来的主进程已经完成了它的命令,返回了。
前面我们提到,在Android应用程序中,每一个进程对应一个ActivityThread实例,所以,这个函数会创建一个thread实例,然后调用ActivityThread.attach函数进一步处理。
Step 7.ActivityThread.attach
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
public final class ActivityThread { ...... private final void attach(boolean system) { ...... if (!system) { ...... IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { } } else { ...... } ...... } ...... }从Step 6中,这里传进来的参数system为false。成员变量mAppThread是一个ApplicationThread实例,我们在前面已经描述过这个实例的作用,它是用来辅助ActivityThread来执行一些操作的。
调用ActivityManagerNative.getDefault函数得到ActivityManagerService的远程接口,即ActivityManagerProxy,接着调用它的attachApplication函数。
Step 8.ActivityManagerProxy.attachApplication
这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
class ActivityManagerProxy implements IActivityManager { ...... public void attachApplication(IApplicationThread app) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(app.asBinder()); mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); } ...... }
这个函数主要是将新进程里面的IApplicationThread实例通过Binder驱动程序传递给ActivityManagerService。
Step 9. ActivityManagerService.attachApplication
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } } ...... }这里通过调用attachApplicationLocked函数进一步处理。
Step 10.ActivityManagerService.attachApplicationLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { // Find the application record that is being attached... either via // the pid if we are running in multiple processes, or just pull the // next app record if we are emulating process with anonymous threads. ProcessRecord app; if (pid != MY_PID && pid >= 0) { synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid); } } else if (mStartingProcesses.size() > 0) { app = mStartingProcesses.remove(0); app.setPid(pid); } else { app = null; } ...... String processName = app.processName; ...... app.thread = thread; ...... boolean badApp = false; ...... // Find any services that should be running in this process... if (!badApp && mPendingServices.size() > 0) { ServiceRecord sr = null; try { for (int i=0; i<mPendingServices.size(); i++) { sr = mPendingServices.get(i); if (app.info.uid != sr.appInfo.uid || !processName.equals(sr.processName)) { continue; } mPendingServices.remove(i); i--; realStartServiceLocked(sr, app); didSomething = true; } } catch (Exception e) { ...... } } ...... return true; } ...... }回忆一下在上面的Step 4中,以新进程的pid值作为key值保存了一个ProcessRecord在mPidsSelfLocked列表中,这里先把它取出来,存放在本地变量app中,并且将app.processName保存在本地变量processName中。
再回忆一下在上面的Step 3中,在成员变量mPendingServices中,保存了一个ServiceRecord,这里通过进程uid和进程名称将它找出来,然后通过realStartServiceLocked函数来进一步处理。
Step 11.ActivityManagerService.realStartServiceLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
class ActivityManagerProxy implements IActivityManager { ...... private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app) throws RemoteException { ...... r.app = app; ...... try { ...... app.thread.scheduleCreateService(r, r.serviceInfo); ...... } finally { ...... } ...... } ...... }
这里的app.thread是一个ApplicationThread对象的远程接口,它是在上面的Step 6创建ActivityThread对象时作为ActivityThread对象的成员变量同时创建的,然后在Step 9中传过来的。然后调用这个远程接口的scheduleCreateService函数回到原来的ActivityThread对象中执行启动服务的操作。
Step 12. ApplicationThreadProxy.scheduleCreateService
这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:
class ApplicationThreadProxy implements IApplicationThread { ...... public final void scheduleCreateService(IBinder token, ServiceInfo info) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(token); info.writeToParcel(data, 0); mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } ...... }
这里通过Binder驱动程序回到新进程的ApplicationThread对象中去执行scheduleCreateService函数。
Step 13.ApplicationThread.scheduleCreateService
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
public final class ActivityThread { ...... private final class ApplicationThread extends ApplicationThreadNative { ...... public final void scheduleCreateService(IBinder token, ServiceInfo info) { CreateServiceData s = new CreateServiceData(); s.token = token; s.info = info; queueOrSendMessage(H.CREATE_SERVICE, s); } ...... } ...... }这里调用ActivityThread的queueOrSendMessage将一个CreateServiceData数据放到消息队列中去,并且分开这个消息。注意,这里已经是在上面Step 4创建的新进程中执行了。
Step 14.ActivityThread.queueOrSendMessage
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
public final class ActivityThread { ...... private final void queueOrSendMessage(int what, Object obj) { queueOrSendMessage(what, obj, 0, 0); } private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) { synchronized (this) { ...... Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; mH.sendMessage(msg); } } ...... }
这里调用成员变量mH的sendMessage函数进行消息分发。这里的mH的类型为H,它继承于Handler类。
Step 15. H.sendMessage
这个函数继承于Handle类的sendMessage函数中,定义在frameworks/base/core/java/android/os/Handler.java文件中。这个函数我们就不看了,有兴趣的读者可以自己研究一下。消息分发以后,就进入到H.handleMessage函数进行处理了。
Step 16. H.handleMessage
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
public final class ActivityThread { ...... private final class H extends Handler { ...... public void handleMessage(Message msg) { ...... switch (msg.what) { ...... case CREATE_SERVICE: handleCreateService((CreateServiceData)msg.obj); break; ...... } ...... } ...... } ...... }这里要处理的消息是CREATE_SERVICE,它调用ActivityThread类的handleCreateService成员函数进一步处理。
Step 17.ActivityThread.handleCreateService
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
public final class ActivityThread { ...... private final void handleCreateService(CreateServiceData data) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo); Service service = null; try { java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance(); } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to instantiate service " + data.info.name + ": " + e.toString(), e); } } try { if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); ContextImpl context = new ContextImpl(); context.init(packageInfo, null, this); Application app = packageInfo.makeApplication(false, mInstrumentation); context.setOuterContext(service); service.attach(context, this, data.info.name, data.token, app, ActivityManagerNative.getDefault()); service.onCreate(); mServices.put(data.token, service); try { ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, 0, 0, 0); } catch (RemoteException e) { // nothing to do. } } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to create service " + data.info.name + ": " + e.toString(), e); } } } ...... }这里的data.info.name就是自定义的服务类shy.luo.ashmem.Server了。
Step 18. ClassLoader.loadClass
这一步实现在上面的ActivityThread.handleCreateService函数中:
java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance();Step 19. Obtain Service
这一步也是实现在上面的ActivityThread.handleCreateService函数中。上面通过ClassLoader.loadClass来导入自定义的服务类shy.luo.ashmem.Server并且创建它的一个实例后,就通过强制类型转换得到一个Service类实例。前面我们说过,自己的服务类必须要继承于Service类,这里就体现出来了为什么要这样做了。
Step 20. Service.onCreate
这一步继续实现在上面的ActivityThread.handleCreateService函数中:
service.onCreate();因为这里的service实际上是一个shy.luo.ashmem.Server类实例,因此,这里就是执行shy.luo.ashmem.Server类的onCreate函数了:
public class Server extends Service { ...... @Override public void onCreate() { ...... } ...... }至此,这个自定义的服务就启动起来了。
这样,Android系统在新进程中启动服务的过程就分析完成了,虽然很复杂,但是条理很清晰。它通过三次Binder进程间通信完成了服务的启动过程,分别是:
一. Step 1至Step 7,从主进程调用到ActivityManagerService进程中,完成新进程的创建;
二. Step 8至Step 11,从新进程调用到ActivityManagerService进程中,获取要在新进程启动的服务的相关信息;
三. Step 12至Step 20,从ActivityManagerService进程又回到新进程中,最终将服务启动起来。
学习完Android系统在新进程中启动服务的过程后,希望读者对Android系统的Service有一个深刻的理解。在编写Android应用程序的时候,尽量把一些计算型的逻辑以Service在形式来实现,使得这些耗时的计算能在一个独立的进程中进行,这样就能保持主进程流畅地响应界面事件,提高用户体验。
老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!
相关推荐
"Android系统在新进程中启动自定义服务过程(startService)的原理" 在 Android 系统中,startService 函数是一个非常重要的函数,它允许开发者在新进程中启动自定义服务。这项技术可以将一些计算型逻辑从主进程中...
(Android系统进程Zygote启动过程的源代码分析UML,Android系统默认Home应用程序(Launcher)的启动过程源代码分析uml,Android系统在新进程中启动自定义服务过程(startService)的原理分析UML,Android应用程序...
##### 3.5 疑问:传说中的zygote进程启动在哪里? `zygote`进程是Android系统中非常重要的一个进程,它负责启动所有基于Dalvik或ART运行的应用程序进程。`zygote`进程的启动是在`init.rc`文件中定义的,具体来说是...
`zygote`进程是Android的核心,它的启动在`.rc`脚本文件中被定义为: ```bash service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server ``` 这意味着`zygote`从`app_main.cpp`...
`onCreate()`在Service首次创建时调用,`onStartCommand()`在每次通过`startService()`启动Service时调用,返回值表示Service的启动行为,`onDestroy()`在Service被销毁时调用。 描述中的“binder继承一个接口,...
- 如果是共享进程,则直接在现有进程中启动新的Activity实例。 - **OnCreate 函数的调用**: - 在Activity实例创建完成后,系统会调用`onCreate()`方法来进行初始化操作。 - 开发者可以在此处设置UI布局、绑定...
2. 启动Service:在需要启动Service的地方调用startService(),传入一个Intent对象,Intent中包含Service的组件名。 3. 绑定Service:使用bindService(),同样需要Intent,同时提供一个ServiceConnection回调,用于...
5. **《Android系统在新进程中启动自定义服务过程(startService)的原理分析.pdf》**:服务是Android四大组件之一,用于执行后台任务。文档详细阐述了startService方法的执行流程,对优化应用性能和理解服务生命周期...
在Android系统启动时,首先由Linux内核加载并执行init进程,这是系统的第一个用户空间进程,其职责是初始化系统环境和启动其他必要的服务。 2. **MAIN FUNCTION(SDK参考文档)** - **Process step:** 1. **...
- **服务启动**:查看`startService()`的调用,理解如何传递Intent参数,以及在Service的`onStartCommand()`中如何处理这些参数。 - **服务绑定**:研究`bindService()`的使用,关注`onBind()`返回的Binder对象,...
4. **客户端绑定服务**:客户端通过startService或bindService启动服务,并获取IBinder对象。 5. **调用服务方法**:客户端通过Stub对象调用服务端的方法。 **应用场景** AIDL广泛应用于需要跨进程通信的场景,...
5. **服务启动和停止**:在Activity中,会有代码片段用于启动(`startService()`)和停止(`stopService()`)服务。 6. **服务生命周期管理**:在适当的地方,如Activity的`onResume()`和`onPause()`中,可能会有...
Android框架体系架构是Android开发中的核心内容,涵盖了UI晋升、组件内核、IPC(Inter-Process Communication,进程间通信)以及数据持久化等关键知识点。本文将详细介绍这些知识,以此来深入理解Android平台的运作...
- **Linux进程**:Android运行在Linux内核之上,每个应用程序都运行在一个独立的Linux进程中。 - **应用程序进程**:指运行在DVM之上的应用程序进程,每个应用程序运行在自己的进程中。 #### 30. SIM卡的EF文件 - ...
- **启动Service**:通过 `startService()` 或 `bindService()` 方法启动Service。 - **前台Service**:通过 `startForeground()` 方法启动,通常用于长时间运行的任务,如音乐播放。 ### 十七、发送短信和打电话的...
- Service是后台运行的组件,理解Service的启动方式(startService()和bindService()),以及生命周期中的关键方法,如onStartCommand()和onBind()。 6. **ContentProvider** - ContentProvider是数据共享的桥梁...
在Android系统中,`am`命令是一个非常强大的工具,它允许开发者通过命令行接口与系统的Activity Manager进行交互,实现对应用程序的各种控制。本篇将详细讲解`am`命令的使用,包括开启Activity、服务和广播,以及...
在Android中,Intent通常用于启动Activity或Service,而Bundle则常作为Intent的一部分,用来传递额外的数据。当创建Intent时,我们可以把Bundle附加到Intent中: ```java Intent intent = new Intent(this, ...
- Service生命周期:了解Service的启动、绑定过程,掌握startService()和bindService()的区别。 - 广播接收器:理解隐式和显式广播,注册方式(静态和动态),以及如何在BroadcastReceiver中响应广播事件。 5. **...