ContentProvider原理

注意:contentprovider的oncreate要先于application的oncreate启动
在应用启动的时候,会通过ActivityThread的attach方法通过远程调用AMS的attachApplication来将ApplicationThread(Binder对象)传递给AMS,同时在该方法中会调用ApplicationThread的bindApplication方法,同样也是跨进程的。该方法最终通过handler转移到ActivityThread中运行,具体为handleBindApplication,在其中主线程会创建application对象并加载contentprovider,注意contentprovider是先被加载的。


image.png

外界无法直接访问ContentProvider,只能通过AMS根据URI来获取对应的ContentProvider的Binder接口IContentProvider,然后再访问响应数据。

contentProvider可以做成多实例,通过属性控制,但是现实中很少采用因为浪费开销。外界访问其增删改查的任何一个方法都会导致contentProvider的创建,并且拉起进程。

比如通过query方法启动contentprovider:
1、通过acquireProvider来获取IContentProvider对象。
2、先检查本端ActivityThread中是否存在ContentProvider了,如果存在就直接返回(返回的是IContentProvider客户端接口对象)。如果没有,就通过远程AMS.getContentProvider方法
3、ContentProvider的启动伴随着进程的启动,启动进程靠的是AMS的startProcessLocked,新进程启动后其入口方法为ActivityThread.main()方法,然后在attach方法中通过attachApplication方法将ApplicationThread作为参数传递给AMS
4、AMS的方法中又调用了ApplicationThread.bindApplication
5、ActivityThread的bindApplication发送BIND_APPLICATION消息给mH使得ActivityThread完成一系列工作,包括(按步骤顺序):

  • 创建ContextImpl和instrumrent
  • 创建Application对象
  • 启动当前进程的ContentProvider并调用其onCreate方法;
    将创建好的Contentprovider保存在AMS中的providerMap中,这样外部调用者就能直接从AMS中获取ContentProvider了。然后调用其onCreate方法
  • 调用Application的onCreate方法

上述四个步骤之后,外部就能在AMS中拿到ContentProvider访问其接口了,但拿到的其实是Binder类型对象IContentProvider。其具体实现是ContentProvider.Transport,所以外界调用query方法时候,是通过调用ContentProvider.Transport中的query方法,其远程调用ContentProvider.query方法,结果通过Binder返回给调用者。
对其他方法的调用类似。

你可能感兴趣的:(ContentProvider原理)