浅析调用android的content provider(二)
来源:互联网 发布:软件招聘网 编辑:程序博客网 时间:2024/06/06 17:40
上一篇文章(http://blog.csdn.net/chenyufei1013/article/details/6586456)中提到应用程序的管理模型。但是,并未作具体的解释,所以本文先把这一块内容稍许解释下,这对跟踪Android的Framework代码会有帮助。
- 主线程消息循环
- 概述
Android 2.3.5的实现中:
- 同一个进程中,只有一个JVM,一个ActivityThread.main。
- 每个java线程中,最多有一个ActivityThread和Looper。
- 每个Looper,可以有多个Handler与之对应。创建Handler的时所在的线程决定了该Handler和那个线程的Looper绑定。
- 可以通过Handler来获取消息和投递消息。
- 初始化Looper环境。
- 创建用于管理主线程的ActivityThread对象。除了ActivityThread之外还有一个类是ApplicationThread;可以理解为ApplicationThread是本进程的服务端,负责处理其它进程的请求的,最终将请求递交给ActivityThread,由ActivityThread来做具体的事情。此部分本节不作介绍。
- 初始化Activity运行环境,并通知相关的后台服务,比如ActivityManagerService。此部分本节不作介绍。
- 进入消息循环。
- 去初始化。此部分本节不作介绍。
具体参见下面的源码分析:
- 一个进程、一个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消息。
- 浅析调用android的content provider(二)
- 浅析调用android的content provider(一)
- 浅析调用android的content provider(一)
- 浅析调用android的content provider(一)
- Android的Content Provider
- android Content Provider详解二
- android Content Provider详解二
- (转)Android Content Provider的应用
- Content Provider启动浅析
- Android开发指导文档(译)--content provider(二)
- Android Content Providers(二)——Contacts Provider
- Android Content Providers(二)——Contacts Provider
- Android之内容提供器Content Provider详解(二)
- Android本地的Content Provider
- Android本地的Content Provider
- android Content Provider的使用
- Android Content Provider的使用
- Android的Content Provider组件
- js基础
- 第7章 Android的Audio系统
- I/O知识集--2 UNIX 类操作系统的网络I/O处理模型
- NIT 1048
- 用const修饰函数 以及引起的附加限制
- 浅析调用android的content provider(二)
- 几个问题
- c 语言宏
- hdu 3835 R(N)
- 【友元类】友元类的访问限制,只在静态编译时有效,在动态链接时,是不受限制的
- hdu 3829 Cat VS Dog
- Android中的用户词库——UserDictionry
- POJ 2309 BST
- NIT 1464