Activity的启动过程

来源:互联网 发布:知乎 金冲及 编辑:程序博客网 时间:2024/06/06 17:02
1、Activity是安卓四大组件之一那么它有是怎么启动的?
答:
由于本人水平有限,有不妥的地方,还望读者指正
我们首先来看startActivityForResult(Intent intent, int requestCode)方法,此方法的说明是:
if the activity you are launching uses the singleTask launch mode, it will not run in your
      task and thus you will immediately receive a cancel result.
我们如果启动的acivity跟我们不在一个task那么我们就不会收到我们发送的requestCode。

我们来分析这个方法:
public void startActivityForResult(Intent intent, int requestCode) {
       if (mParent == null) {
           Instrumentation.ActivityResult ar =
               mInstrumentation.execStartActivity(
                   this, mMainThread.getApplicationThread(), mToken, this,
                   intent, requestCode);
           if (ar != null) {
               mMainThread.sendActivityResult(
                   mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                   ar.getResultData());
           }
           if (requestCode >= 0) {
               // If this start is requesting a result, we can avoid making
               // the activity visible until the result is received.  Setting
               // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
               // activity hidden during this time, to avoid flickering.
               // This can only be done when a result is requested because
               // that guarantees we will get information back when the
               // activity is finished, no matter what happens to it.
               mStartedActivity = true;
           }
       } else {
           mParent.startActivityFromChild(this, intent, requestCode);
       }
   }
activity使用Instrumentation的execStartActivity方法
mInstrumentation.execStartActivity(
                   this, mMainThread.getApplicationThread(), mToken, this,
                   intent, requestCode);
方法我们来看execStartActivity方法:
   public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
           Intent intent, int requestCode)
   {
       IApplicationThread whoThread = (IApplicationThread) contextThread;
       if (mActivityMonitors != null) {
           synchronized (mSync) {
               final int N = mActivityMonitors.size();
               for (int i=0; i<N; i++) {
                   final ActivityMonitor am = mActivityMonitors.get(i);
                   if (am.match(who, null, intent)) {
                       am.mHits++;
                       if (am.isBlocking()) {
                           return requestCode >= 0 ? am.getResult() : null;
                       }
                       break;
                   }
               }
           }
       }
       try {
           intent.setAllowFds(false);
           //这个是开启activity的方法,我们来看看
           int result = ActivityManagerNative.getDefault()
               .startActivity(whoThread, intent,
                       intent.resolveTypeIfNeeded(who.getContentResolver()),
                       null, 0, token, target != null ? target.mEmbeddedID : null,
                       requestCode, false, false, null, null, false);
           checkStartActivityResult(result, intent);
       } catch (RemoteException e) {
       }
       return null;
    }
   
    我们来看看ActivityManagerNative类的源码在frameworks\base\core\java\android\app下边
    我们来看ActivityManagerNative.getDefault()方法
    /**
    * Retrieve the system's default/global activity manager.
    */
   static public IActivityManager getDefault() {
       return gDefault.get();
   }
此方法的作用是检索系统默认的全局的activity manager,我们在来看gDefalut.get()是什么东东呢

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
       protected IActivityManager create() {
           IBinder b = ServiceManager.getService("activity");
           if (false) {
               Log.v("ActivityManager", "default service binder = " + b);
           }
           IActivityManager am = asInterface(b);
           if (false) {
               Log.v("ActivityManager", "default service = " + am);
           }
           return am;
       }
   };
其实gDefalut.get()就是protected IActivityManager create();返回的IActivityManager对象,
我们分析一下create()方法,首先 IBinder b = ServiceManager.getService("activity");
返回的我们属性的ActivityManager,我们来看看ServiceManager.getService("activity")的源码
(\frameworks\base\core\java\android\os):
/**
    * Returns a reference to a service with the given name.
    * 
    * @param name the name of the service to get
    * @return a reference to the service, or <code>null</code> if the service doesn't exist
    */
   public static IBinder getService(String name) {
       try {
        //首先从缓存中找。
           IBinder service = sCache.get(name);
           if (service != null) {
               return service;
           } else {
          //如果没有缓存,那么就获取一个
               return getIServiceManager().getService(name);
           }
       } catch (RemoteException e) {
           Log.e(TAG, "error in getService", e);
       }
       return null;


   }
 
我们如何获取一个本地的ServiceManager呢:  
 
 我们来看看 getIServiceManager()源码:
   private static IServiceManager getIServiceManager() {
       if (sServiceManager != null) {
           return sServiceManager;
       }

       // Find the service manager
       sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
       return sServiceManager;
    }
    其中主要的方法是 ServiceManagerNative.asInterface(BinderInternal.getContextObject()),用来查找我们要找的本地系统服务。
我们来看看它的源码,此方法是将Binder转化为一个service manager interface,如果需要就生成一个代理;
/**
    * Cast a Binder object into a service manager interface, generating
    * a proxy if needed.
    */
   static public IServiceManager asInterface(IBinder obj)
   {
       if (obj == null) {
           return null;
       }
       IServiceManager in =
           (IServiceManager)obj.queryLocalInterface(descriptor);
       if (in != null) {
           return in;
       }
       
       return new ServiceManagerProxy(obj);
   }

我们先来看 IServiceManager in =(IServiceManager)obj.queryLocalInterface(descriptor);这句话
其中的descriptor是怎么来的呢,ServiceManagerNative实现了接口IServiceManager,
public abstract class ServiceManagerNative extends Binder implements IServiceManager
我们来看看IServiceManager源码:
   static final String descriptor = "android.os.IServiceManager";
然后我们接着来看queryLocalInterface方法,我们在obj(BinderInternal.getContextObject())源码中看看:

/**
    * Return the global "context object" of the system.  This is usually
    * an implementation of IServiceManager, which you can use to find
    * other services.
    */
   public static final native IBinder getContextObject();
   
 它是一个native方法,作用是返回一个系统的全局的 “context object”,这个context object是什么呢,我们先暂且往下看
 它通常是一个实现了IServiceManager的一个你可以使用它去找到其他的services,这个context object还需再专门要研究。
 我们已经知道它的作用了,我们接着分析queryLocalInterface方法,他是IBinder的方法,我们来看看它的源码:
 
   /**
    * Attempt to retrieve a local implementation of an interface
    * for this Binder object.  If null is returned, you will need
    * to instantiate a proxy class to marshall calls through
    * the transact() method.
    */
   public IInterface queryLocalInterface(String descriptor);
   
从上面分析我们知道,实现IBinder的类的作用了,可以找到其他服务,这个方法就是对它的实现,我们读一读方法说明:
试图检索一个本地的实现了descriptor接口的也就是( "android.os.IServiceManager")的类的对象,如果检索失败了,
你需要去实例化一个代理类去通过transact()方法去安排调用:
这也就解释了:
return new ServiceManagerProxy(obj);的作用了ServiceManagerProxy()源码:

public ServiceManagerProxy(IBinder remote) {
       mRemote = remote;
  }

我们取了IServiceManager的实例了,那么我们接着看ServiceManager.getService()方法中的getIServiceManager().getService(name);的getService(name)方法
我们来看实例:看看ServiceManagerProxy是怎么操作的:
public IBinder getService(String name) throws RemoteException {
       Parcel data = Parcel.obtain();
       Parcel reply = Parcel.obtain();
       data.writeInterfaceToken(IServiceManager.descriptor);
       data.writeString(name);
       mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
       IBinder binder = reply.readStrongBinder();
       reply.recycle();
       data.recycle();
       return binder;
   }
   
我们来分析分析这个方法:mRemote是上面的BinderInternal.getContextObject()返回的IBinder实例,那么我们来看看IBinder中transact方法的解释,

   /**
    * Perform a generic operation with the object.
    * 
    * @param code The action to perform.  This should
    * be a number between {@link #FIRST_CALL_TRANSACTION} and
    * {@link #LAST_CALL_TRANSACTION}.
    * @param data Marshalled data to send to the target.  Must not be null.
    * If you are not sending any data, you must create an empty Parcel
    * that is given here.
    * @param reply Marshalled data to be received from the target.  May be
    * null if you are not interested in the return value.
    * @param flags Additional operation flags.  Either 0 for a normal
    * RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
    */
   public boolean transact(int code, Parcel data, Parcel reply, int flags)
       throws RemoteException;
       
此方法的作用是通过serverManager中实现的transact方法,来跟系统中的ServerMagager通信,然后获取到ServerMagager回复,即reply,
并且把需要通信的server的IBinder对象返回给当前进程,我们现在请求通信的是acitivyManagerService。
 
现在我们通过IBinder已经和AcitvityManagerService通讯上了,接着分析代码:
在private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() 中,我们已经分析完成
IBinder b = ServiceManager.getService("activity");的作用是建立与系统的ActivityManagerService的通讯,并装成IServiceManager,
接下来我们继续分析IActivityManager am = asInterface(b);的作用,后面同学们自己可以查看源码了,先分析到这里吧,









         


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 养的花蔫了怎么办 养的小鸡很大了怎么办 养的小兔子死了怎么办 小狗出现爬跨行为怎么办 养的小狗总做吞咬人的行为怎么办 螃蟹和柿子一起吃了怎么办 指甲上月牙没了怎么办 手指上月牙没了怎么办 指甲上没半月牙怎么办 电动车车牌被偷了怎么办 警察拖车拖坏了怎么办 6岁儿童牙疼怎么办 小白单车不退押金怎么办 光盘放笔记本电脑里读不出来怎么办 cd光盘读不出来怎么办 最近脸干的不行怎么办 脸感觉干的不行怎么办 新生儿睡觉黑白颠倒了怎么办 婴儿吐水和奶花怎么办 刚刚出生的宝宝拉肚子怎么办 刚出生的婴儿拉肚子怎么办 新生儿5天拉稀水怎么办 10个月孩子拉肚子怎么办 不满月的宝宝拉肚子怎么办 一周岁宝宝发烧腹泻呕吐怎么办 6个月宝宝37度怎么办 1岁宝宝发烧37.2怎么办 新生儿发烧37度3怎么办 两个月宝宝抵抗力差怎么办 6月宝宝着凉拉稀怎么办 六个月的宝宝拉肚子怎么办 衣服颜色太深了怎么办 一多半宝宝爱喝水不爱吃饭怎么办 十个月宝宝不爱吃饭怎么办 十个月宝宝突然不爱吃饭怎么办 二十个月宝宝不爱吃饭怎么办 十个月的宝宝不爱吃饭怎么办 6年级学生数学差怎么办 打印机打不出来就是一张白纸怎么办 wps表格下拉数字不递增怎么办 wps表格圈怎么打出来怎么办