【1】Android源码阅读:一个Activity是如何启动的?

这几天心情很不好,我也不知道是什么原因,虽然一直的习惯是找到事物/念想产生的原因,但是这一回却真是找不到原因了,哈哈,人丑还是要多读书啊。不过,不管怎样,不管周围的人的变得怎样,周围的世界变得怎样,依然要保持学习,做自己想做的事,做一个开心而有价值的人。

想起一首诗以自勉:

自小刺头深草里,而今渐觉出蓬蒿。 
时人不识凌云木,直待凌云始道高。
         -唐代杜荀鹤 《小松》

Activity的启动从startActivity起:

 startActivity(new Intent(MainActivity.this, LayerListActivity.class));

会调到Activity的源码:

/**
     * Same as {@link #startActivity(Intent, Bundle)} with no options  //方法的多态,同名不同参;
     * specified.
     *
     * @param intent The intent to start.
     *
     * @throws android.content.ActivityNotFoundException//如果在清单文件中没找到对应的activity,会抛出这个异常;
     *
     * @see {@link #startActivity(Intent, Bundle)}
     * @see #startActivityForResult
     */
    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

先了解一下 类ActivityNotFoundException:

//是运行时异常的子类
//包含两个构造方法
package android.content;
public class ActivityNotFoundException extends  RuntimeException 
{
    public ActivityNotFoundException()
    {
    }

    public ActivityNotFoundException(String name)
    {
        super(name);
    }
};

关于Java 异常类层次结构图:

这里写图片描述

回到正题,然后调用同名方法:

@Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

其中作为if 条件的ActivityOptions,兼容包是ActivityOptionsCompat,和页面切换的转场动画相关。它的主要方法是:

这里写图片描述

不管怎样,最后都调到 activity.startActivityForResult :

public class Activity extends ContextThemeWrapper  
        implements LayoutInflater.Factory,  
        Window.Callback, KeyEvent.Callback,  
        OnCreateContextMenuListener, ComponentCallbacks {  

    ......  

    public void startActivityForResult(Intent intent, int requestCode) {  
        if (mParent == null) {  
            Instrumentation.ActivityResult ar =  
                mInstrumentation.execStartActivity(  
                this, mMainThread.getApplicationThread(), mToken, this,  
                intent, requestCode);  
            ......  
        } else {  
            ......  
        }  


    ......  

}  
  1. 这里的mInstrumentation的类型是Intrumentation,定义在frameworks/base/core/java/android/app/Instrumentation.java文件中,它用来监控应用程序和系统的交互。ActivityResult 是它的内部静态类。
  2. 这里的mMainThread也是Activity类的成员变量,它的类型是ActivityThread,它代表的是应用程序的主线程。
  3. 通过mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象,后面我们会看到,ActivityManagerService会使用它来和ActivityThread来进行进程间通信。
  4. 需注意的是,这里的mMainThread代表的是Launcher应用程序运行的进程。
  5. 这里的mToken也是Activity类的成员变量,它是一个Binder对象的远程接口。
public ApplicationThread getApplicationThread()
    {
        return mAppThread;
    }

private class ApplicationThread extends ApplicationThreadNative{

}

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
}

public interface IApplicationThread extends IInterface {
    void schedulePauseActivity();
    void scheduleStopActivity();
    void scheduleResumeActivity();
    void scheduleDestroyActivity();
    ......
}

其中IInterface 接口如下:

package android.os;

/**
 * Base class for Binder interfaces.  When defining a new interface,
 * you must derive it from IInterface.
 */
public interface IInterface
{
    public IBinder asBinder();
}

其中IBinder 接口如下:

public interface IBinder {
 public boolean transact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException;
}

紧接着调用:

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
/**
     * Cast a Binder object into an activity manager interface, generating
     * a proxy if needed.
     */
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ActivityManagerProxy(obj);
    }

    /**
     * Retrieve the system's default/global activity manager.
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }
}

返回的是ActivityManagerProxy 对象:

class ActivityManagerProxy implements IActivityManager
{
    public ActivityManagerProxy(IBinder remote)
    {
        mRemote = remote;
    }

    public IBinder asBinder()
    {
        return mRemote;
    }

    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeString(callingPackage);
        intent.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrongBinder(resultTo);
        data.writeString(resultWho);
        data.writeInt(requestCode);
        data.writeInt(startFlags);
        if (profilerInfo != null) {
            data.writeInt(1);
            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        if (options != null) {
            data.writeInt(1);
            options.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }
}

关于ActivityManager家族的结构图:

这里写图片描述

通过上述代码中的mRemote.transact 与AMS进行通信,由Binder驱动程序进入到ActivityManagerService的startActivity函数:

public final class ActivityManagerService extends ActivityManagerNative  
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  

    ......  

    public final int startActivity(IApplicationThread caller,  
            Intent intent, String resolvedType, Uri[] grantedUriPermissions,  
            int grantedMode, IBinder resultTo,  
            String resultWho, int requestCode, boolean onlyIfNeeded,  
            boolean debug) {  
        return mMainStack.startActivityMayWait(caller, intent, resolvedType,  
            grantedUriPermissions, grantedMode, resultTo, resultWho,  
            requestCode, onlyIfNeeded, debug, null, null);  
    }  


    ......  

} 

这里只是简单地将操作转发给成员变量mMainStack的startActivityMayWait函数,这里的mMainStack的类型为ActivityStack。

public class ActivityStack {  

    ......  

    final int startActivityMayWait(){};  //1、解析Intent,保存ActivityInfo;
    final int startActivityLocked(){};//2、创建即将要启动的Activity的相关信息,并保存在ActivityRecord 变量中;
    final int startActivityUncheckedLocked(){};//3、获得intent的标志值---activity的启动方式;
    private final void startActivityLocked(ActivityRecord r, boolean newTask,  
            boolean doResume){};
   final boolean resumeTopActivityLocked(){};//4、看要启动的Activity是否就是当前处理Resumed状态的Activity,如果是的话,那就什么都不用做,直接返回就可以了;否则再看一下系统当前是否休眠状态,如果是的话,再看看要启动的Activity是否就是当前处于堆栈顶端的Activity,如果是的话,也是什么都不用做。
   private final void startPausingLocked(){};//5、prev.app.thread是一个ApplicationThread对象的远程接口,通过调用这个远程接口的schedulePauseActivity来通知Launcher进入Paused状态;


}  

对参数intent的内容进行解析,得到要启动的Activity的相关信息,保存在aInfo变量中:

ActivityInfo aInfo;  
        try {  
            ResolveInfo rInfo =  
                AppGlobals.getPackageManager().resolveIntent(  
                intent, resolvedType,  
                PackageManager.MATCH_DEFAULT_ONLY  
                | ActivityManagerService.STOCK_PM_FLAGS);  
            aInfo = rInfo != null ? rInfo.activityInfo : null;  

关于ActivityInfo:

这里写图片描述

从ActivityStack类的startPausingLocked 方法进入ApplicationThreadProxy :

class ApplicationThreadProxy implements IApplicationThread {  

    ......  

    public final void schedulePauseActivity(IBinder token, boolean finished,  
    boolean userLeaving, int configChanges) throws RemoteException {  
        Parcel data = Parcel.obtain();  
        data.writeInterfaceToken(IApplicationThread.descriptor);  
        data.writeStrongBinder(token);  
        data.writeInt(finished ? 1 : 0);  
        data.writeInt(userLeaving ? 1 :0);  
        data.writeInt(configChanges);  
        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,  
            IBinder.FLAG_ONEWAY);  
        data.recycle();  
    }  

    ......  

}  

这个函数通过Binder进程间通信机制进入到ApplicationThread.schedulePauseActivity函数中。

与ApplicationThread相关的类调用关系结构图:

这里写图片描述

ApplicationThread.schedulePauseActivity:

public final class ActivityThread {

    ......

    private final class ApplicationThread extends ApplicationThreadNative {

        ......

        public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges) {
            queueOrSendMessage(
                finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                token,
                (userLeaving ? 1 : 0),
                configChanges);
        }

        ......

    }
    ......
}

这里调用的函数queueOrSendMessage是ActivityThread类的成员函数。

public final class ActivityThread {  

    ......  

    private final void queueOrSendMessage(int what, Object obj, int arg1) {  
        queueOrSendMessage(what, obj, arg1, 0);  
    }  

    private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {  
        synchronized (this) {  
            ......  
            Message msg = Message.obtain();  
            msg.what = what;  
            msg.obj = obj;  
            msg.arg1 = arg1;  
            msg.arg2 = arg2;  
            mH.sendMessage(msg);  
        }  
    }  

    ......  

}  

这里首先将相关信息组装成一个msg,然后通过mH成员变量发送出去,mH的类型是H,继承于Handler类,是ActivityThread的内部类,因此,这个消息最后由H.handleMessage来处理。

public final class ActivityThread {  

    ......  

    private final class H extends Handler {  

        ......  

        public void handleMessage(Message msg) {  
            ......  
            switch (msg.what) {  

            ......  

            case PAUSE_ACTIVITY:  
                handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);  
                maybeSnapshot();  
                break;  

            ......  

            }  
        ......  

    }  

    ......  

}  

ActivityThread.handlePauseActivity( ) 做了三件事:

  1. 如果userLeaving为true,则通过调用performUserLeavingActivity函数来调用Activity.onUserLeaveHint通知Activity,用户要离开它了;
  2. 调用performPauseActivity函数来调用Activity.onPause函数,我们知道,在Activity的生命周期中,当它要让位于其它的Activity时,系统就会调用它的onPause函数;
  3. 它通知 ActivityManagerService,这个Activity已经进入Paused状态了,ActivityManagerService现在可以完成未竟的事情,即启动MainActivity了。
class ActivityManagerProxy implements IActivityManager  
{  
    ......  

    public void activityPaused(IBinder token, Bundle state) throws RemoteException  
    {  
        Parcel data = Parcel.obtain();  
        Parcel reply = Parcel.obtain();  
        data.writeInterfaceToken(IActivityManager.descriptor);  
        data.writeStrongBinder(token);  
        data.writeBundle(state);  
        mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);  
        reply.readException();  
        data.recycle();  
        reply.recycle();  
    }  

    ......  

}

这里通过Binder进程间通信机制就进入到ActivityManagerService.activityPaused函数中去了。

public final class ActivityManagerService extends ActivityManagerNative  
            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
    ......  

    public final void activityPaused(IBinder token, Bundle icicle) {  

        ......  

        final long origId = Binder.clearCallingIdentity();  
        mMainStack.activityPaused(token, icicle, false);  

        ......  
    }  

    ......  

}  

这里,又再次进入到ActivityStack类中,执行activityPaused函数。

参考致谢:
(1)、Android应用程序内部启动Activity过程(startActivity)的源代码分析
(2)、Android FrameWork——ActivityManager框架
(3)、深入理解Activity启动流程(三)–Activity启动的详细流程1
(4)、Android Activity学习笔记——Activity的启动和创建

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值