想问下xml字符串在main函数解析是我的青春物语没有问题题,但是在service的调用函数里面就有问题了,是什么原因呢?

web项目MyWebPro,web.xml为:
&?xml&version=&1.0&&encoding=&UTF-8&?&
&web-app&xmlns:xsi=&http://www.w3.org/2001/XMLSchema-instance&&xmlns=&/xml/ns/javaee&&xsi:schemaLocation=&/xml/ns/javaee&/xml/ns/javaee/web-app_2_5.xsd&&id=&WebApp_ID&&version=&2.5&&
&&&display-name&MyWebPro&/display-name&
&&&&servlet&
&&&&&&&servlet-name&apn&/servlet-name&
&&&&&&&servlet-class&com.cjq.servlet.APNServlet&/servlet-class&
&&&/servlet&
&&&servlet-mapping&
&&&&&&&servlet-name&apn&/servlet-name&
&&&&&&&url-pattern&/*&/url-pattern&
&&&/servlet-mapping&
&&&welcome-file-list&
&&&&&welcome-file&index.html&/welcome-file&
&&&/welcome-file-list&
&/web-app&
APNServlet如下:
package&com.cjq.
import&java.io.IOE
import&javax.servlet.ServletE
import&javax.servlet.http.HttpS
import&javax.servlet.http.HttpServletR
import&javax.servlet.http.HttpServletR
import&com.cjq.push.PushB
import&com.cjq.push.PushU
public&class&APNServlet&&extends&HttpServlet&{
protected&void&doGet(HttpServletRequest&req,&HttpServletResponse&resp)
throws&ServletException,&IOException&{
String&username&=&req.getParameter(&username&);
String&msg&=&req.getParameter(&message&);
String&title&=&req.getParameter(&title&);
PushBean&pb&=&new&PushBean();
pb.setMessage(msg);
pb.setUri(&&);
pb.setUsername(username);
pb.setTitle(title);
PushUtils.sendSingle(pb);
}&catch&(Exception&e)&{
//&TODO&Auto-generated&catch&block
e.printStackTrace();
protected&void&doPost(HttpServletRequest&req,&HttpServletResponse&resp)
throws&ServletException,&IOException&{
doGet(req,resp);
测试类Test:
package&com.cjq.
public&class&Test&{
public&static&void&main(String[]&args)&throws&Exception&{
PushBean&bean&=&new&PushBean();
bean.setUsername(&6ad464b32c4e265d8542&);
bean.setMessage(&aaa&);
bean.setTitle(&aaa&);
bean.setUri(&&);
PushUtils.sendSingle(bean);
直接运行Test类中main方法,能正常下推消息。
在IE中输入:http://192.168.16.38:8080/MyWebPro/UI/index.html?username=e0d4acb7cf29c&message=textapn&title=testapn
APNServlet正常运行,但PushUtils.sendSingle(pb);这一句实际未下推消息,也无任何报错信息。
这是为什么呢?
回复讨论(解决方案)
PushUtils.sendSingle(bean);
catch(Exception&e){
//打印异常看看
PushUtils.sendSingle(bean);
catch(Exception&e){
//打印异常看看
前面已有说明,无任何异常。
通过放在servlet里的代码不能下推消息。单独main函数可正常下推消息&。
debug看下servlet中执行到那段代码了吗?
debug看下servlet中执行到那段代码了吗?
也已有说明,APNServlet正常运行。
只是运行完后,消息不下推。
PushUtils.sendSingle(pb);&&这句前面打印日志或断点看下,如果进来了,看看有没进这你这个方法:PushUtils.sendSingle(pb),或者pb有哪个属性为空?
PushUtils.sendSingle(pb);&&这句前面打印日志或断点看下,如果进来了,看看有没进这你这个方法:PushUtils.sendSingle(pb),或者pb有哪个属性为空?
说明,所有的每一句都有执行。
问题点是,main执行完后,可下推。
在sevlet中执行完后,无任务反应:再强调,细到每句都有执行。
已解决...在servlet或action中调用webservice时,由于androidpn初始化服务需要时间,所以没能下推消息 .
在test类中运行时,由于运行时,webservice已是初始化完成,所以可下推.
解决方法,在servlet中将消息下推放到线程中去,并让线程休眠5-10秒即可.按照wiki( 上最下方给的客户端代码,直接调用bdf中webservice的demo报如下错误。
Exception in thread &main& org.springframework.ws.soap.axiom.AxiomSoapMessageCreationException: Unknown content type 'text/charset=UTF-8'
at org.springframework.ws.soap.axiom.AxiomSoapMessageFactory.getSoapEnvelopeNamespace(AxiomSoapMessageFactory.java:282)
at org.springframework.ws.soap.axiom.AxiomSoapMessageFactory.createAxiomSoapMessage(AxiomSoapMessageFactory.java:242)
at org.springframework.ws.soap.axiom.AxiomSoapMessageFactory.createWebServiceMessage(AxiomSoapMessageFactory.java:213)
at org.springframework.ws.soap.axiom.AxiomSoapMessageFactory.createWebServiceMessage(AxiomSoapMessageFactory.java:81)
at org.springframework.ws.transport.AbstractWebServiceConnection.receive(AbstractWebServiceConnection.java:90)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:589)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:537)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:384)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:378)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:370)
at com.bstek.bdf.webservice.client.WebServiceClient.marshalSendAndReceive(WebServiceClient.java:52)
at com.bstek.bdf.test.webservice.DemoWebserviceClient.main(DemoWebserviceClient.java:20)
Back to top
Back to top70765人阅读
&& & & &在编写Android应用程序时,我们一般将一些计算型的逻辑放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通过startService函数来启动这个服务。在本文中,将详细分析主进程是如何通过startService函数来在新进程中启动自定义服务的。&& & & &在主进程调用startService函数时,会通过Binder进程间通信机制来通知ActivitManagerService来创建新进程,并且启动指定的服务。在Android系统中,Binder进程间通信机制使用非常广泛,因此,希望读者在继续阅读下面的内容之前,对Android系统和Binder进程间通信机制有一定的了解,具体可以参考前面一文。&& & & &关于startService的具体用法,可以参考前面一文中用到的实例,它是Activity类的一个成员函数:package shy.luo.
public class Client extends Activity implements OnClickListener {
IMemoryService memoryService =
public void onCreate(Bundle savedInstanceState) {
IMemoryService ms = getMemoryService();
if(ms == null) {
startService(new Intent(&shy.luo.ashmem.server&));
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=&/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&&
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.
public class Server extends Service {
public IBinder onBind(Intent intent) {
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关键字,回忆一下前面这篇文章,就会知道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 {
public void run() {
// Critical services...
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 mS
public static void setSystemProcess() {
ActivityManagerService m = mS
ServiceManager.addService(&activity&, m);
} catch (PackageManager.NameNotFoundException e) {
public static final Context main(int factoryTest) {
ActivityManagerService m = thr.mS
}&& & & & 这样,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();
}&& & & & 参数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);
}&& & & & 这里的参数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.
if (!bringUpServiceLocked(r, service.getFlags(), false)) {
return new ComponentName(&!&, &Service process is bad&);
}&& & & &函数首先通过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.processN
// 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) {
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}&& & & &这里的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) {
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.removed =
synchronized (mPidsSelfLocked) {
this.mPidsSelfLocked.put(pid, app);
} 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();
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
}&& & & & 从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.
if (pid != MY_PID && pid &= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
} else if (mStartingProcesses.size() & 0) {
app = mStartingProcesses.remove(0);
app.setPid(pid);
String processName = app.processN
app.thread =
boolean badApp =
// Find any services that should be running in this process...
if (!badApp && mPendingServices.size() & 0) {
ServiceRecord sr =
for (int i=0; i&mPendingServices.size(); i++) {
sr = mPendingServices.get(i);
if (.uid != sr.appInfo.uid
|| !processName.equals(sr.processName)) {
mPendingServices.remove(i);
realStartServiceLocked(sr, app);
didSomething =
} catch (Exception e) {
}&& & & &回忆一下在上面的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 {
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();
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 =
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);
}&& & & &这里要处理的消息是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(
.applicationInfo);
Service service =
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl..name).newInstance();
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
&Unable to instantiate service & + .name
+ &: & + e.toString(), e);
if (localLOGV) Slog.v(TAG, &Creating service & + .name);
ContextImpl context = new ContextImpl();
context.init(packageInfo, null, this);
Application app = packageInfo.makeApplication(false, mInstrumentation);
context.setOuterContext(service);
service.attach(context, this, .name, data.token, app,
ActivityManagerNative.getDefault());
service.onCreate();
mServices.put(data.token, service);
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 & + .name
+ &: & + e.toString(), e);
}&& & & &这里的.name就是自定义的服务类shy.luo.ashmem.Server了。&& & & &Step 18. ClassLoader.loadClass&& & & &这一步实现在上面的ActivityThread.handleCreateService函数中:java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl..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 {
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在形式来实现,使得这些耗时的计算能在一个独立的进程中进行,这样就能保持主进程流畅地响应界面事件,提高用户体验。老罗的新浪微博:,欢迎关注!
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:5213473次
积分:28200
积分:28200
排名:第75名
原创:122篇
评论:6317条
本博客所有文章均为原创,欢迎交流,欢迎转载;转载请勿篡改内容,并且注明出处,禁止用于商业目的,谢谢!
《Android系统源代码情景分析》
电子工业出版社
本书繁体版已经成功输出到台湾
新浪微博:
QQ交流群:
(1000人群,已满)
(1000人群,已满)
(500人群,未满)
(500人群,已满)
(500人群,已满)
PS:请勿同时加入多个群,一经发现,永久封号,谢谢!
文章:122篇
阅读:5228612

我要回帖

更多关于 没有问题的我们下载 的文章

 

随机推荐