Android进阶之路Android开发

Android源码阅读,绑定Service源码分析

2018-04-03  本文已影响149人  Sky_Blue
一、怎么去分析绑定服务的流程
带着下面这些疑问去看源码
  1.Service是怎么创建的?
  2.Service是怎么绑定的?
  3.Service的回调在哪里调用?
二、一般绑定一个创建好的远程服务(服务的创建我就不多说)
public void bind(View view) {
      Intent service = new Intent();
      service.setAction("com.wen.user.service");
      service.setPackage("com.wen.routerdemo");
      // 创建并绑定服务
      bindService(service, conn, Context.BIND_AUTO_CREATE);
}
// 绑定解绑的回调类
ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {         
        Toast.makeText(TestActivity.this, "onServiceConnected", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        Toast.makeText(TestActivity.this, "onServiceDisconnected", Toast.LENGTH_SHORT).show();
    }
};
三、bindService源码分析
@Override
public boolean bindService(Intent service, ServiceConnection conn,int flags) {
    // mBase其实是ContextImpl
    return mBase.bindService(service, conn, flags);
}
四、找到ContextImpl类的bindService方法
@Override
public boolean bindService(Intent service, ServiceConnection conn,int flags) {
    // mMainThread是ActivityThread
    return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),Process.myUserHandle());
}
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user) {      
    IServiceConnection sd;
    if (conn == null) {
        // 回调空会抛异常
        throw new IllegalArgumentException("connection is null");
    }
    if (mPackageInfo != null) {
        // 创建ServiceDispatcher类和IServiceConnection的实现类
        // ServiceDispatcher类是对ServiceConnection回调和IServiceConnection等一些参数的封装
        // 这个类很关键,后面的回调就是在这里
        sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
    } 
    try {
        IBinder token = getActivityToken();
        // ActivityManager.getService()通过Binder机制获取到ActivityManagerService
        // 最终会调用ActivityManagerService的bindService方法
        int res = ActivityManager.getService().bindService(
            mMainThread.getApplicationThread(), getActivityToken(), service,
            service.resolveTypeIfNeeded(getContentResolver()),
            sd, flags, getOpPackageName(), user.getIdentifier());           
        return res != 0;
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}
五、找到ActivityManagerService的bindService方法
public int bindService(IApplicationThread caller, IBinder token, Intent service,
        String resolvedType, IServiceConnection connection, int flags, String callingPackage,
        int userId) throws TransactionTooLargeException {
    synchronized(this) {
        // 这里又去调用ActiveServices类的bindServiceLocked方法
        return mServices.bindServiceLocked(caller, token, service,
                resolvedType, connection, flags, callingPackage, userId);
    }
}
五、再去找ActiveServices类的bindServiceLocked方法
 int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
        String resolvedType, final IServiceConnection connection, int flags,
        String callingPackage, final int userId) throws TransactionTooLargeException {
        
    // 对查找服务信息的封装
    ServiceLookupResult res =
        retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
                Binder.getCallingUid(), userId, true, callerFg, isBindExternal);
    
    ServiceRecord s = res.record;
    try {
      
        // 传的flags标记
        if ((flags&Context.BIND_AUTO_CREATE) != 0) {
            s.lastActivity = SystemClock.uptimeMillis();
            // 创建Service的重要方法,返回是空,所以继续往下走。
            if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                    permissionsReviewRequired) != null) {
                return 0;
            }
        }   
        if (s.app != null && b.intent.received) {
                         
            if (b.intent.apps.size() == 1 && b.intent.doRebind) {
                // 绑定Service的关键方法
                requestServiceBindingLocked(s, b.intent, callerFg, true);
            }
        } else if (!b.intent.requested) {
            // 绑定Service的关键方法
            requestServiceBindingLocked(s, b.intent, callerFg, false);
        }
    } finally {
        Binder.restoreCallingIdentity(origId);
    }
    return 1;
}
// 创建Service的重要方法
 private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
        boolean whileRestarting, boolean permissionsReviewRequired)
        throws TransactionTooLargeException {
    final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
    final String procName = r.processName;
    String hostingType = "service";
    ProcessRecord app;
    if (!isolated) {
        app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
    
        if (app != null && app.thread != null) {
            try {
                app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                // 锁定要开启的Service
                realStartServiceLocked(r, app, execInFg);
                // 这里返回null
                return null;
            } catch (TransactionTooLargeException e) {
                throw e;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting service " + r.shortName, e);
            }

         
        }
    } else {   
        app = r.isolatedProc;
    
    }     
    return null;
}
 // 锁定要开启的Service
 private final void realStartServiceLocked(ServiceRecord r,
        ProcessRecord app, boolean execInFg) throws RemoteException {
    
    try {
        // 终于看到希望,调用ActivityThread去创建Service
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
        mAm.appDiedLocked(app);
        throw e;
    } finally {
        if (!created) {
            // Keep the executeNesting count accurate.
            final boolean inDestroying = mDestroyingServices.contains(r);
            serviceDoneExecutingLocked(r, inDestroying, inDestroying);

            // Cleanup.
            if (newService) {
                app.services.remove(r);
                r.app = null;
            }

            // Retry.
            if (!inDestroying) {
                scheduleServiceRestartLocked(r, false);
            }
        }
    }
}
// 绑定服务的关键方法
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
        boolean execInFg, boolean rebind) throws TransactionTooLargeException {
   
    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);
            
        } 
    }
    return true;
}

在这里终于看到,调用ActivityThread去创建Service的方法:app.thread.scheduleCreateService()和绑定Service的方法:r.app.thread.scheduleBindService()。

六、Service的创建

找到ActivityThread里面scheduleCreateService方法,这方法通过Handler发送个消息,然后来到handleCreateService方法。

private void handleCreateService(CreateServiceData data) {      
    LoadedApk packageInfo = getPackageInfoNoCheck(
            data.info.applicationInfo, data.compatInfo);
    Service service = null;
    try {
        // 通过反射创建Service
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        service = (Service) cl.loadClass(data.info.name).newInstance();
    } catch (Exception e) {  
    }
    try {        
        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);
        Application app = packageInfo.makeApplication(false, mInstrumentation);
        // 调用Service的attach方法
        service.attach(context, this, data.info.name, data.token, app,ActivityManager.getService());
        // 调用Service的onCreate()方法
        service.onCreate();
        //  添加到ArrayMap集合
        mServices.put(data.token, service);
    } catch (Exception e) {
    }
}
七、Service的绑定

找到ActivityThread里面scheduleBindService方法,这方法通过Handler发送个消息,然后来到handleBindService方法。

private void handleBindService(BindServiceData data) {
    // 从集合里面获取Service
    Service s = mServices.get(data.token);
    if (s != null) {
        try {
            data.intent.setExtrasClassLoader(s.getClassLoader());
            data.intent.prepareToEnterProcess();
            try {
                if (!data.rebind) {
                    // 调用服务的onBind()方法,得到IBinder
                    IBinder binder = s.onBind(data.intent);
                    // 调用ActivityServiceManager的publishService方法
                    ActivityManager.getService().publishService(data.token, data.intent, binder);
                } else {
                    s.onRebind(data.intent);
                    ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                }
            
            } catch (RemoteException ex) {
            }
        } catch (Exception e) {   
        }
    }
}
// 这里是ActivityServiceManager类里面的方法
public void publishService(IBinder token, Intent intent, IBinder service) {
    synchronized(this) {
        // 调用ActiveServices的publishServiceLocked
        mServices.publishServiceLocked((ServiceRecord)token, intent, service);
    }
}
 // ActiveServices的publishServiceLocked
 void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    try {      
        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);
                        try {
                            // 调用IServiceConnection的connected方法
                            // IServiceConnection在ContextImpl类bindServiceCommon方法里面创建
                            // 去ContextImpl类bindServiceCommon方法找到IServiceConnection的实现类ServiceDispatcher里面的mIServiceConnection
                            // 也就是InnerConnection-->>connected(ComponentName name, IBinder service, boolean dead)
                            c.conn.connected(r.name, service, false);
                        } catch (Exception e) {
                            
                        }
                    }
                }
            }
        }
    } finally {
        Binder.restoreCallingIdentity(origId);
    }
}
 //实现类ServiceDispatcher,这个类在LoadedApk类里面
 static final class ServiceDispatcher {
        private final ServiceDispatcher.InnerConnection mIServiceConnection;
        private final ServiceConnection mConnection;

        private static class InnerConnection extends IServiceConnection.Stub {
            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

            InnerConnection(LoadedApk.ServiceDispatcher sd) {
                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
            }
            // 1.先来到这里
            public void connected(ComponentName name, IBinder service, boolean dead)
                    throws RemoteException {
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    // 2.调用ServiceDispatcher的connected方法
                    sd.connected(name, service, dead);
                }
            }
        }

        ServiceDispatcher(ServiceConnection conn,
                Context context, Handler activityThread, int flags) {
            mIServiceConnection = new InnerConnection(this);
            mConnection = conn;
            mContext = context;
            mActivityThread = activityThread;
            mLocation = new ServiceConnectionLeaked(null);
            mLocation.fillInStackTrace();
            mFlags = flags;
        }

    
        // 2.调用ServiceDispatcher执行connected方法
        public void connected(ComponentName name, IBinder service, boolean dead) {
            if (mActivityThread != null) {
                mActivityThread.post(new RunConnection(name, service, 0, dead));
            } else {
                // 3. 调用doConnected方法
                doConnected(name, service, dead);
            }
        }

        public void doConnected(ComponentName name, IBinder service, boolean dead) {
            // 删掉N行代码
            synchronized (this) {
                // If there is a new service, it is now connected.
                if (service != null) {
                    // 执行ServiceConnection连接的回调
                    mConnection.onServiceConnected(name, service);
                }
            }
        }
        
    }
八、总结
1.Service的创建是在ActivityThread类的handleCreateService方法里通过反射进行创建的,创建后紧接着调用Service的attach()方法,然后调用onCreate()方法。
2.紧跟着Service的onBind(Intent intent)方法是在ActivityThread类的handleBindService方法里调用
3.最后绑定服务的客户端ServiceConnection 类的回调是在ServiceDispatcher这个类调用的 doConnected()方法回调。
上一篇下一篇

猜你喜欢

热点阅读