- 浏览: 638178 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
luo_ganlin:
别的不多说,点个赞!
关于Android隐式启动Activity -
IWSo:
谢楼主!研究了好久,原来是这样!
android中如何让LinearLayout实现点击时背景图片切换 -
fantao005x:
粘帖的不错
android中如何让listview的内容全部显示出来 -
learner576539763:
Android_gqs 写道请问博主,Viewstub 可实现 ...
android中ViewStub使用 -
goontosoon:
抄的什么啊,狗屁不通
对ContentProvider中getType(Uri uri)
在编写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>
- startService(new Intent("shy.luo.ashmem.server"));
- package shy.luo.ashmem;
- ......
- public class Server extends Service {
- ......
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- @Override
- public void onCreate() {
- ......
- }
- ......
- }
先来看看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);
- }
- ......
- }
- ......
- }
- 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;
- ......
- }
- }
回到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;
- }
- ......
- }
参数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;
- }
- }
- ......
- }
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;
- }
- }
- ......
- }
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 {
- ......
- }
- ......
- }
- ......
- }
调用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 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);
- }
- ......
- }
- ......
- }
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;
- ......
- }
- ......
- }
- ......
- }
- ......
- }
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);
- }
- }
- }
- ......
- }
Step 18. ClassLoader.loadClass
这一步实现在上面的ActivityThread.handleCreateService函数中:
- java.lang.ClassLoader cl = packageInfo.getClassLoader();
- service = (Service) cl.loadClass(data.info.name).newInstance();
这一步也是实现在上面的ActivityThread.handleCreateService函数中。上面通过ClassLoader.loadClass来导入自定义的服务类shy.luo.ashmem.Server并且创建它的一个实例后,就通过强制类型转换得到一个Service类实例。前面我们说过,自己的服务类必须要继承于Service类,这里就体现出来了为什么要这样做了。
Step 20. Service.onCreate
这一步继续实现在上面的ActivityThread.handleCreateService函数中:
- service.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在形式来实现,使得这些耗时的计算能在一个独立的进程中进行,这样就能保持主进程流畅地响应界面事件,提高用户体验。
发表评论
-
EditText软键盘弹出问题解决
2013-02-26 23:10 1471当带有EditView的activity第一次进入时,第一 ... -
android中获取系统相关属性adb
2012-11-15 14:41 22031.查看系统相关属性可以通过: adb shell ... -
Android使用Intent传递复杂参数及复杂参数列表
2012-11-05 17:29 1640刚开始一直纠结于Intent只能put像int, ... -
解决P6200/P6800扩展卡第三方软件不可写的BUG
2012-11-05 17:01 1037从XDA看来的步骤:1. Using a root-e ... -
android 中跟actionbar相关的属性
2012-10-25 17:07 2486android:uiOptions 这个属性用于设置A ... -
source insight使用快捷键
2012-10-25 10:59 1562F5指定行号,实现行跳转,在遇到编译错误的时候,能特 ... -
android中推出应用比较有效率的方法
2012-10-11 16:57 1168添加一个全局变量作为程序退出的标记(boolean类型) ... -
declare-styleable的使用
2012-10-09 13:59 1182declare-styleable的使用 decl ... -
android程序安全的建议
2012-09-29 14:58 5321如果保证自己的 ... -
Java自带的线程池ThreadPoolExecutor详细介绍说明和实例应用
2012-09-29 14:45 1082从 Java 5 开始,Java 提供了自己的线程池。线 ... -
android应用检测更新代码
2012-09-24 17:40 1857JAVA代码: UpdateManager.java ... -
adb命令详解
2012-09-19 15:04 2896Android adb的常用命令略解 Androi ... -
android中屏蔽其它系统按钮的dialog
2012-09-18 10:13 1657public class MyProgress ... -
如何给Scrollview里内容截屏并生成bitmap,注意:Scrollview里面内容较多有滚动了
2012-09-18 10:07 1650使用for循环递归累加其内部的子控件的高度: p ... -
wakelock的使用
2012-09-17 11:44 10088PowerManager.WakerLock是我分析St ... -
启动另外一个apk
2012-09-14 13:16 907这篇博文主要是获取其他apk程序的启动的主intent, ... -
android中全屏的方法
2012-09-14 13:04 9741.直接代码编写 @Override ... -
android:installLocation简析
2012-09-12 15:25 1124在Froyo(android 2.2,API Le ... -
外部apk启动启动另外一个apk
2012-09-06 17:54 1058public class TestingBroadc ... -
listview如何实现圆角
2012-09-05 17:32 1944首先呢,我们还是看几个示图:(这是360推出的一款天气预 ...
相关推荐
本资源提供了关于Android中Service的源码,重点展示了Service的生命周期以及如何在Service中播放音乐。通过分析和学习这个`ServiceTest`项目,我们可以深入理解Service的工作原理和用法。 首先,Service的生命周期...
Service的源码分析对于深入理解Android系统的工作原理和优化应用性能至关重要。本篇将详细介绍Android Service的源码学习及其关键知识点。 首先,我们来了解Service的基本生命周期。在Android中,Service的启动与...
"Android ActivityManagerService 源码分析----Activity ...通过对 ActivityManagerService 的源码分析,我们可以更好地理解 Android 系统中 Activity 生命周期的管理机制,从而更好地开发和维护 Android 应用程序。
### Android源码分析工具及方法 #### 一、引言 在进行Android系统源码的深入研究时,选择合适的工具和技术对于提高效率至关重要。本文旨在介绍一些常用的Android源码分析工具及其使用方法,并通过实际案例展示如何...
本篇文章将深入解析"android service 简单实例源代码",帮助你理解如何在Android应用中创建和使用Service。 首先,我们来了解一下Service的基本概念。Service主要分为两种类型:标准Service和IntentService。标准...
源码中包含了对这些协议的具体实现,解析和构建邮件头信息,以及身份验证过程。 2. **存储管理**: 邮件存储通常采用SQLite数据库,源码中包含数据库操作的类,如`EmailDatabaseHelper`,用于创建和维护数据库表。...
本教程将深入探讨如何正确地停止一个Android Service,同时结合源码分析其内部机制。 首先,理解Service的生命周期至关重要。Service的启动有两种方式:startService()和bindService()。startService()用于启动一个...
在Android平台上,开发一个简易本地音乐播放器是一项常见的任务,对于初学者来说...通过分析和学习这个源码,开发者可以深入了解Android音频播放、UI设计以及应用架构等方面的知识,对提升Android开发技能非常有帮助。
本篇文章将深入探讨Service的两种主要应用:`startService`和`bindService`,并结合提供的源码分析进行详细解释。 首先,`startService`是启动一个Service的方式,它适合那些不需要与启动Service的应用组件直接交互...
### Android的APN开发源码分析 #### 一、Android数据连接原理 Android的数据连接机制主要是基于PPP(Point-to-Point Protocol)的方式实现的。PPP协议是一种广泛使用的串行链路通信协议,它允许用户通过拨号或其他...
"Android Service(1234) 源码"是一个博客示例项目,旨在深入解析Android Service的实现机制。这个项目包括了ServiceDemo,我们可以从中学习到如何创建、启动、绑定Service以及使用AIDL(Android Interface ...
本压缩包中的源码提供了从Android应用程序中调用Web Service的示例,帮助开发者理解和实践这一过程。以下是关于这个主题的详细知识点: 1. Web Service基本概念:Web Service是一种基于互联网的标准,允许不同系统...
在“最牛网-深入浅出Android Service(2) 源码”这个主题中,我们将深入探讨Service的工作原理和源码分析,以帮助开发者更好地理解和使用这一关键组件。 首先,Service的基本用法包括在AndroidManifest.xml中声明...
本篇将深入探讨如何在Android 9.0中实现分屏模式,并提供相关的源码分析。 一、分屏模式概述 在Android 5.0(Lollipop)版本引入了多窗口模式,而在Android 7.0(Nougat)中正式引入了分屏模式。在Android 9.0中,...
通过分析这个基于Android Studio的音乐播放器源码,开发者不仅可以学习到如何构建一个完整的音乐播放应用,还能深入理解Android平台上的多媒体处理、用户界面设计、服务组件使用等核心概念,为今后的Android开发打下...
本资料“Android应用源码之16.Service学习(2).zip”提供了关于Service的深入学习资源,通过源码分析,我们可以更深入地理解Service的工作原理和使用方式。 Service的生命周期: 1. 创建:当通过startService()或...
深入源码分析,Service的启动流程涉及AMS(Activity Manager Service)和服务的 Binder 通信。startService()实际上是通过AMS启动Service,AMS负责调度和管理所有的应用组件。当调用startService()时,会发送一个...
`ActivityManagerService`是Android系统中的核心服务之一,负责管理所有应用程序的生命周期和任务栈。它会根据Intent的类别和目标组件,决定如何启动或恢复Activity。 接下来,`ActivityManagerService`会通过...
本文将深入探讨Android开发中的核心概念,源码分析方法以及如何利用这些源码进行学习。 一、Android系统架构 Android系统分为四个主要层次:Linux内核层、系统库层、应用程序框架层和应用程序层。源码揭示了这四层...
"Android应用源码之app更新,实现service下载.zip"是一个示例项目,展示了如何在Android应用中实现后台服务(Service)进行自动或手动的APK更新下载。下面我们将深入探讨这个主题,讲解相关知识点。 首先,我们需要...