Activtiy

一、activity的生命周期

 

  • 整体生命周期onCreate()    onStart()   onResume()    onPause()   onStop()    onDestory()
  • 打开页面  onCreate()   onStart()   onResume()
  • 打开新的activity    A-->onPause()  B-->onCreate()  B-->onStart  B-->onResume  A-->onStop
  • 关闭一个界面  onPause()  onStop()  onDestory()
  • home键  onPause()   onStop()
  • 打开最小化的界面   onStart()   onResume()
  • singleTask  模式   onNewIntent()
  • 异常关闭   onSaveInstanceState()     onRestoreInstanceState()
  • 横竖屏切换,onpasue()  onSaveInstanceState()  onStop()   onDestory()   onCreate()  onstoreInstanceState()   onStart()  onResume(),可以设置切换屏幕禁止调用生命周期 configChanges="orientation | screenSize | keyboardHidden"

二、打开activity

    (1)startActivtiy

  intent = new Intent(MainActivity.this, RecyclerViewActivity.class);
  startActivity(intent);
  finish();

    (2)startActivityForResult(requestCode要大于0,看源码)

  intent = new Intent(MainActivity.this, RecyclerViewActivity.class);
  startActivityForResult(intent,100);

    (3)intent传递参数类型

      八大基本类型及其数组,parcelable,serializable,bundle,intent

三、app启动流程

      手机桌面也是一个app,每一个应用的icon都罗列在Launcher上,点击icon触发事件。

      

 第一步:

       手机桌面也是一个app,每一个应用的icon都罗列在Launcher上,点击要启动应用的icon,会调用LauncherActivity的onListItemClick(),首先获取Intent(隐式方式启动,因为不在同一进程,然后调用startActivity(intent),然后会调用startActivityForResult()

 @Override
protected void onListItemClick(ListView l, View v, int position, long id) {
   Intent intent = intentForPosition(position);
   startActivity(intent);
}


public void startActivity(Intent intent, @Nullable Bundle options) {
    // ...
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1);
    }
    // ...
}


//Intent的获取
 protected Intent intentForPosition(int position) {
        ActivityAdapter adapter = (ActivityAdapter) mAdapter;
        return adapter.intentForPosition(position);
 }
 public Intent intentForPosition(int position) {
     if (mActivitiesList == null) {
          return null;
     }

     Intent intent = new Intent(mIntent);
     ListItem item = mActivitiesList.get(position);
     intent.setClassName(item.packageName, item.className);
     if (item.extras != null) {
         intent.putExtras(item.extras);
     }
     return intent;
  }

       运行到startActivityForResult(),因为第一次启动app的activity,所以mParent为空,走if逻辑,使用mInstrumenttation调用execStartActivity(),第二参数是applicationThread,插入Instrumentation是管理activity的工具类,创建,启动,管理生命周期,一个进程只有一个Instrumentation实例。

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {//第一次启动,mParent为空,走这边的逻辑
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            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;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

       execStartActivity()会获取ActivityManagerService的Binder代理类ActivityManagerProxy(继承了IActivityManager),调用代理类的startActivity方法,IPC通信,实际调用的是ActivityManagerService的startActivity()

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            //检查启动activity的结果
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

第一步开启分支:解析AcivityManagerService代理类的获取:

public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
  };

第二步,代码运行到ActivityManagerService中的startActivity方法中,首先会调用startActivityAsUser依次调用方法,是对根据启动模式的处理,方法如下:

ActivityManagerService.startActivity() 
ActivityManagerService.startActivityAsUser() 
//7.0新增ActivityStarter(原本是ActivityStackSupervisor处理该过程)
ActivityStarter.startActivityMayWait() 
ActivityStarter.startActivityLocked()  //创建ActivityRecord对象,
ActivityStarter.startActivityUnchecked() //调度ActivityRecord和Task
ActivityStack.startActivityLocked() 
ActivityStackSupervisor.resumeTopActivitiesLocked()
ActivityStack.resumeTopActivityInnerLocked() 

第三步、执行栈顶Activity的onPause方法

>ActivityStack.startPausingLocked()
>IApplicationThread.schudulePauseActivity()
>ActivityThread.sendMessage()
>ActivityThread.H.sendMessage();
>ActivityThread.H.handleMessage()
>ActivityThread.handlePauseActivity()
>ActivityThread.performPauseActivity()
>Activity.performPause()
>Activity.onPause()
>ActivityManagerNative.getDefault().activityPaused(token)
>ActivityManagerService.activityPaused()
>ActivityStack.activityPausedLocked()
>ActivityStack.completePauseLocked()
>ActivityStack.resumeTopActivitiesLocked()
>ActivityStack.resumeTopActivityLocked()
>ActivityStack.resumeTopActivityInnerLocked()
>ActivityStack.startSpecificActivityLocked

第四步、运行到startSpecificActivityLocked方法,它会判断activity所在的进程是否创建,如果存在,则调用realStartActivityLock方法开始创建activity,如果不存在进程,则调用startProcessLocked方法去启动进程

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);

    r.task.stack.setLaunchTime(r);

    if (app != null && app.thread != null) {
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                    || !"android".equals(r.info.packageName)) {
                // Don't add this if it is a platform component that is marked
                // to run in multiple processes, because this is actually
                // part of the framework so doesn't make sense to track as a
                // separate apk in the process.
                app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                        mService.mProcessStats);
            }
            //创建activity
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }

        // If a dead object exception was thrown -- fall through to
        // restart the application.
    }

    //初始化进程
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

第四步分支一:进程不存在,开启进程

          ActivityManagerService会通过socket与Zygote通讯,并告知Zygote进程fork出一个新的应用程序进程,然后执行ActivityThread的mani方法,源码如下:

 public static void main(String[] args) {
        ...
        //looper的源码
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        ...
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

      在main方法中,创建了ActivityThread类的对象thread,并调用thread的attach方法,参数为false,attach方法源码如下:

private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ...
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            //ActivityManagerService的接口
            final IActivityManager mgr = ActivityManager.getService();
            try {
                //初始化applicaton
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
           
        } 

        ...
        ViewRootImpl.addConfigCallback(configChangedCallback);
    }

       其中mAppThread是ApplicationThread类初始化的对象,ApplicationThread类是ActivityThread类的内部类,实现了IApplicationThread.Stub,用于远程服务ActivityManagerService与app交互。

       ActivityManager的getService方法获取IActivityManager,用于app与远程服务ActivityManagerService交互,调用attachApplication方法,参数为mAppThread,这是方便让远程服务ActivityManagerService拿到IApplicationThread的引用,方便调用ApplicationThread类的方法。

      现在看下ActivityManagerService的attachApplication的方法,里面调用了里面调用了attachApplicaionLocked方法,源码如下:

 @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }


private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

            ...
            //远程服务启动时阻塞的
            if (app.instr != null) {
                thread.bindApplication(processName, appInfo, providers,
                        app.instr.mClass,
                        profilerInfo, app.instr.mArguments,
                        app.instr.mWatcher,
                        app.instr.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
            } else {
                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
            }

         ...
       //创建待启动的activity
       // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }

        return true;
    }

上述源码里调用了ApplicationThread的bindApplication方法,服务端线程挂起,直到生成application,然后往下运行创建activity,源码如下:

 public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial) {

            if (services != null) {
                // Setup the service cache in the ServiceManager
                ServiceManager.initServiceCache(services);
            }

            setCoreSettings(coreSettings);

            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            data.providers = providers;
            data.instrumentationName = instrumentationName;
            data.instrumentationArgs = instrumentationArgs;
            data.instrumentationWatcher = instrumentationWatcher;
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableBinderTracking = enableBinderTracking;
            data.trackAllocation = trackAllocation;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            data.buildSerial = buildSerial;
            sendMessage(H.BIND_APPLICATION, data);
        }

这里给H(H是ActivityThread的内部类,继承了Handler,是Handler的一个实例对象)发送了bind_Application消息,消息处理时,调用了ActivityThread的handleBindApplication方法,源码如下:

  case BIND_APPLICATION:
       Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
       AppBindData data = (AppBindData)msg.obj;
       handleBindApplication(data);
       Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
       break;


private void handleBindApplication(AppBindData data) {

        ...
        // Continue loading instrumentation.
        if (ii != null) {
            final ApplicationInfo instrApp = new ApplicationInfo();
            ii.copyTo(instrApp);
            instrApp.initForUser(UserHandle.myUserId());
            final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                    appContext.getClassLoader(), false, true, false);
            final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);

            try {
                final ClassLoader cl = instrContext.getClassLoader();
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            } catch (Exception e) {
                throw new RuntimeException(
                    "Unable to instantiate instrumentation "
                    + data.instrumentationName + ": " + e.toString(), e);
            }

            final ComponentName component = new ComponentName(ii.packageName, ii.name);
            mInstrumentation.init(this, instrContext, appContext, component,
                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);

            if (mProfiler.profileFile != null && !ii.handleProfiling
                    && mProfiler.profileFd == null) {
                mProfiler.handlingProfiling = true;
                final File file = new File(mProfiler.profileFile);
                file.getParentFile().mkdirs();
                Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
            }
        } else {
            mInstrumentation = new Instrumentation();
        }

        if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
            dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
        } else {
            // Small heap, clamp to the current growth limit and let the heap release
            // pages after the growth limit to the non growth limit capacity. b/18387825
            dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
        }

        // Allow disk access during application and provider setup. This could
        // block processing ordered broadcasts, but later processing would
        // probably end up doing the same disk access.
        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
        try {
            // If the app is being launched for full backup or restore, bring it up in
            // a restricted environment with the base application class.
            //内部通过反射机制
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;

            // don't bring up providers in restricted mode; they may depend on the
            // app's custom Application class
            if (!data.restrictedBackupMode) {
                if (!ArrayUtils.isEmpty(data.providers)) {
                    installContentProviders(app, data.providers);
                    // For process that contains content providers, we want to
                    // ensure that the JIT is enabled "at some point".
                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
                }
            }

            // Do this after providers, since instrumentation tests generally start their
            // test thread at this point, and we don't want that racing.
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
            catch (Exception e) {
                throw new RuntimeException(
                    "Exception thrown in onCreate() of "
                    + data.instrumentationName + ": " + e.toString(), e);
            }

            try {
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()
                        + ": " + e.toString(), e);
                }
            }
        } finally {
            StrictMode.setThreadPolicy(savedPolicy);
        }

       ...
    }

       首先创建了mInstrumentation类实例对象,然后创建Application,然后调用applicaion的oncreate方法。

第五步、

      上面说到创建activity,mStackSupervisor.attachApplicationLocked(app):用于创建Activity,mStackSupervisor是AMS的成员变量,为Activity堆栈管理辅助类实例,该方法最终会调用ApplicationThread类的scheduleLaunchActivity方法,该方法也是类似于第一步,向ActivityThread的消息队列发送创建Activity的消息,最终在ActivityThread中完成创建Activity的操作,
 

第四步分支二、启动activity

ApplicationThread类的scheduleLaunchActivity方法

activity的启动原理

注:

(1)IApplicationThread 和 IActivityManager 是一对配套的 AIDL 接口,IActivityManager 负责 Activity -> ActivityManagerService 的通讯,IApplicationThread 负责 ActivityManagerService -> Activity 的通讯,双向通讯的绑定是在 Activity 拿到同 ActivityManagerService 通讯的 AIDL 时把自己的 IApplicationThread 也就是反向 AIDL 接口交给 ActivityManagerService ,这样2者形成 AIDL 双向通讯

四、activity的context和application的context区别

(1)继承关系

  • activity继承自ContextThemeWrapper--->再继承ContextWrapper--->Context,多个activity就多个context实例
  • Application继承自ContextWrapper--->再继承Context,一个app就一个application  context
  • Service继承自ContextWrapper--->再继承Context,多个service就多个context实例

(2)使用场景

activity的context是activity本身,applicationContext是application本身,生命周期不一样。

五、

IActivityManager    ActivityManagerservice    ActivityManagerNative   ActivityManagerProxy

 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();
    }
  @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case START_ACTIVITY_TRANSACTION:

六、

IApplicationThread   ApplicationThread   ApplicationThreadNative  ApplicaitonThreadProxy

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
    /**
     * Cast a Binder object into an application thread interface, generating
     * a proxy if needed.
     */
    static public IApplicationThread asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IApplicationThread in =
            (IApplicationThread)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        
        return new ApplicationThreadProxy(obj);
    }
    
    public ApplicationThreadNative() {
        attachInterface(this, descriptor);
    }
 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:
private class ApplicationThread extends ApplicationThreadNative {

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值