浅析调用android的content provider(二)

来源:互联网 发布:软件招聘网 编辑:程序博客网 时间:2024/06/06 17:40

        上一篇文章(http://blog.csdn.net/chenyufei1013/article/details/6586456)中提到应用程序的管理模型。但是,并未作具体的解释,所以本文先把这一块内容稍许解释下,这对跟踪Android的Framework代码会有帮助。

  • 主线程消息循环
  • 概述

        Android 2.3.5的实现中:

  1. 同一个进程中,只有一个JVM,一个ActivityThread.main。
  2. 每个java线程中,最多有一个ActivityThread和Looper。
  3. 每个Looper,可以有多个Handler与之对应。创建Handler的时所在的线程决定了该Handler和那个线程的Looper绑定。
  4. 可以通过Handler来获取消息和投递消息。
        主线程(ActivityThread.main)的消息循环是由Looper类来实现的。Looper中处理的是消息,由Message类来封装。可以通过Handler类来和创建和投递消息。主线程的大致流程如下:
  1. 初始化Looper环境。
  2. 创建用于管理主线程的ActivityThread对象。除了ActivityThread之外还有一个类是ApplicationThread;可以理解为ApplicationThread是本进程的服务端,负责处理其它进程的请求的,最终将请求递交给ActivityThread,由ActivityThread来做具体的事情。此部分本节不作介绍。
  3. 初始化Activity运行环境,并通知相关的后台服务,比如ActivityManagerService。此部分本节不作介绍。
  4. 进入消息循环。
  5. 去初始化。此部分本节不作介绍。

        具体参见下面的源码分析:

  • 一个进程、一个JVM、一个ActivityThread.main

        关于这个问题不作太多解析,牵扯到的源码比较多,具体的参考下面的连个调用序列即可。应用进程都是通过zygote进程fork出来的(启动应用的流程可以参考这里),zygote进程接收处理socket消息的循环为ZygoteConnection.run(),调用到ZygoteInit.main的过程为:

ZygoteConnection.run  ZygoteConnection.runOnce    Zygote.forkAndSpecialize // 此处仅fork和初始化    ZygoteConnection.handleChildProc // 此处便开始执行      RuntimeInit.zygoteInit        Process.invokeStaticMain          ZygoteInit.MethodAndArgsCaller            ZygoteInit.main // 此处可以和下面的栈接上。

        ZygoteInit.main调用到Activity.onCreate的栈为(取自eclipse代码调试时的栈信息):

HelloOnDrawActivity.onCreate(Bundle) line: 14Instrumentation.callActivityOnCreate(Activity, Bundle) line: 1123ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2364ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2417ActivityThread.access$2100(ActivityThread, ActivityThread$ActivityRecord, Intent) line: 116ActivityThread$H.handleMessage(Message) line: 1794ActivityThread$H(Handler).dispatchMessage(Message) line: 99Looper.loop() line: 123ActivityThread.main(String[]) line: 4203Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]Method.invoke(Object, Object...) line: 521ZygoteInit$MethodAndArgsCaller.run() line: 791ZygoteInit.main(String[]) line: 549NativeStart.main(String[]) line: not available [native method]

  • 初始化Looper

        初始化Looper的语句为Looper.prepareMainLooper()。该函数首先调用prepare():

    if (sThreadLocal.get() != null) {        throw new RuntimeException("Only one Looper may be created per thread");    }    sThreadLocal.set(new Looper());

        ThreadLocal和Thread的关系可以简单描述如下,具体可以参见ThreadLocal.get()的代码。
        1.同一个线程,不同的ThreadLocal,存储位置不同。
        2.同一个ThreadLocal,在不同的线程中,存储位置不同。
        此处由于sThreadLocal是static的,故可认为只有一个ThreadLocal,那么每个线程中,ThreadLocal.get到的都是同一份,即每个线程只能有一个Looper,可以通过Looper.myLooper()获取;Looper.getMainLooper()可以获取ActivityThread.main中的Looper。
        然后是调用setMainLooper(myLooper());设置为main Looper。接下来设置标志位,若支持多进程,则允许main Looper退出。

    if (Process.supportsProcesses()) {        myLooper().mQueue.mQuitAllowed = false;    }

  • 进入消息循环

        进入消息循环的语句为Looper.loop(),该函数主要是获取当前线程的消息队列,然后对每条消息调用如下函数:

    msg.target.dispatchMessage(msg);

        实际上是调用Handler的dispatchMessage函数;

    public void dispatchMessage(Message msg) {        if (msg.callback != null) {            handleCallback(msg); // 处理msg的callback        } else {            if (mCallback != null) {                if (mCallback.handleMessage(msg)) { // 处理Handler的callback                    return;                }            }            handleMessage(msg); // 处理消息体。此处实际上是调用Handler子类的handleMessage函数。        }    }

  • 获取、发送消息

        若是要往消息循环中发送消息,可以通过Handler类,按如下步骤即可。

        1.初始化Handler。初始化Handler的过程如下:

    mLooper = Looper.myLooper(); // 绑定当前线程的Looper    if (mLooper == null) { // 没有则报错。        throw new RuntimeException(            "Can't create handler inside thread that has not called Looper.prepare()");    }    mQueue = mLooper.mQueue; // 绑定消息队列    mCallback = null; // 没callback

        2.获取消息。获取消息可以通过Handler.obtainMessage函数
        3.发送消息。发送消息可以通过Handler.sendEmptyMessage等相关函数。


  • 应用进程和ActivityManangerService之间的通信

        应用进程和ActivityManangerService之间的通信是通过IBinder的,IBinder只是一种调用方式罢了,具体的调用内容都是定义在Framework中相关的类中的。IBinder是基于C/S模型的,既然是相互通信,自然应用程序既是服务端又是客户端。下面分别分析之:

        1. 应用进程作为客户端
        当应用进程作为客户端时,两端的通信定义在文件ActivityManagerNative.java中。比如:ActivityThread的初始化方法attach中:

    IActivityManager mgr = ActivityManagerNative.getDefault();
        是通过ActivityManagerNative获取ActivityManagerService的代理对象ActivityManagerProxy的。

    gDefault = asInterface(b);
        asInterface方法会new一个新的ActivityManagerProxy对象返回给应用进程用。而ActivityManagerProxy中的方法都会调用transact方法,这个方法通过IBinder最终会调到ActivityManagerNative.onTransact方法中。由于ActivityManangerService继承自ActivityManagerNative,onTransact方法又会掉入ActivityManangerService中实现的IActivityManager接口中,从而完成应用程序对ActivityManangerService的调用。

        2.应用进程作为服务端

        这个过程和上面是类似的,只是它采用的通信类定义在ApplicationThreadNative.java中。当ActivityManangerService拿到ApplicationThreadProxy对象时,然后会通过IBinder调入了ApplicationThreadNative的onTransact方法中,最终调入了ApplicationThread方法中。跟踪ApplicationThread中的方法会发现它最终调用了如下语句:

    mH.sendMessage(msg);

        实际上是通过上面提到的mH的Handler往主线程的消息循环中发消息。比如:ApplicationThread.scheduleLaunchActivity的方法实际上是向主线程中发送H.LAUNCH_ACTIVITY消息。


原创粉丝点击