这篇文章主要解释一下startActivity(intent)方法,基于android的源码。大家都很熟悉这么这2行代码:

Intent intent = new Intent(v.getContext(),ManagePhoneidActivity.class);startActivity(intent);
这是activity的跳转的基本代码。下面我们就看看它是怎么执行的?


1、startActivity(intent)的源码:

@Override    public void startActivity(Intent intent) {        startActivityForResult(intent, -1);    }
大家都对startActivityForResult这个方法也熟悉吧。这就是父子activity传值的时候常用的方法。


2、startActivityForResult(intent, -1)的源码:


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);        }    }
解释:(1) mInstrumentation是Activity类的成员变量,它的类型是Intrumentation,它用来监控应用程序和系统的交互。


(2)mMainThread也是Activity类的成员变量,它的类型是ActivityThread,它代表的是应用程序的主线程。这里通过mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象 。

(3)mToken也是Activity类的成员变量,它是一个Binder对象的远程接口。

3、execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode)的源码:

public ActivityResult execStartActivity(            Context who, IBinder contextThread, IBinder token, Activity target,            Intent intent, int requestCode) {        IApplicationThread whoThread = (IApplicationThread) contextThread;        if (mActivityMonitors != null) {            。。。。        }        try {            intent.setAllowFds(false);            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;    }

解释:(1)getDefault()函数返回的是一个ActivityManagerProxy对象的引用,也就是说,ActivityManager得到了一个本地代理。

ActivityManagerNative.getDefault()的源码:

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

gDefault的源码:


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;        }    };

asInterface(b)的源码:

/**     * 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);    }
上面的代码看到返回什么值了吗? ActivityManagerProxy


4、startActivity的源码:

class ActivityManagerProxy implements IActivityManager{    public ActivityManagerProxy(IBinder remote)    {        mRemote = remote;    }  。。。。。。public int startActivity(IApplicationThread caller, Intent intent,            String resolvedType, Uri[] grantedUriPermissions, int grantedMode,            IBinder resultTo, String resultWho,            int requestCode, boolean onlyIfNeeded,            boolean debug, String profileFile, ParcelFileDescriptor profileFd,            boolean autoStopProfiler) throws RemoteException {        Parcel data = Parcel.obtain();        Parcel reply = Parcel.obtain();        data.writeInterfaceToken(IActivityManager.descriptor);        data.writeStrongBinder(caller != null ? caller.asBinder() : null);        intent.writeToParcel(data, 0);        data.writeString(resolvedType);        data.writeTypedArray(grantedUriPermissions, 0);        data.writeInt(grantedMode);        data.writeStrongBinder(resultTo);        data.writeString(resultWho);        data.writeInt(requestCode);        data.writeInt(onlyIfNeeded ? 1 : 0);        data.writeInt(debug ? 1 : 0);        data.writeString(profileFile);        if (profileFd != null) {            data.writeInt(1);            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);        } else {            data.writeInt(0);        }        data.writeInt(autoStopProfiler ? 1 : 0);        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);        reply.readException();        int result = reply.readInt();        reply.recycle();        data.recycle();        return result;    }}
这是最重要的代码:
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);


调用远端代理的transact()函数,而这个mRemote就是ActivityManagerNative的Binder接口。

就到这吧。













更多相关文章

  1. Android(安卓)SQLiteOpenHelper使用和源码详解
  2. 编译Android版本的libmad
  3. Android之grafika源码阅读
  4. andriod 源码树
  5. Application has stopped unexpectedly. Please try again." and
  6. Android(安卓)ListView pull up to refresh 改造
  7. Android,子类访问父类私有成员
  8. 解决eclipse中overlaps the location of another project: 'xxxx
  9. 源码分析Android(安卓)AMS WMS PMS

随机推荐

  1. mysql group by 对多个字段进行分组操作
  2. 基于JPQL实现纯SQL语句方法详解
  3. MySQL删除表的三种方式(小结)
  4. MySQL复制表的三种方式(小结)
  5. mysql声明游标的方法
  6. mysql中写判断语句的方法总结
  7. MySQL主从复制延迟原因以及解决方案
  8. MySQL8安装Installer版的图文教程
  9. Mysql如何在linux中实现定时备份
  10. MySQL 函数索引的优化方案