`
daojin
  • 浏览: 697857 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

谈谈Activity如何启动的

 
阅读更多

调用栈如下

ActivityManagerService.java

              public void systemReady(final Runnable goingCallback) 传入goingCallback = null,

ActivityStack.java

                final boolean resumeTopActivityLocked(ActivityRecord prev) 传入 null

                       

    ActivityRecord next = topRunningActivityLocked(null); //判断有没有Activity在运行。

                    
        if (next == null) {
                             // There are no more activities!  Let's just start up the
                     // Launcher...
            if (mMainStack) {
                return mService.startHomeActivityLocked();
            }
        }

            

 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
                        null, null, 0, 0, 0, false, false, null);

 然后是

ActivityStack.java 中的

    final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType,
            Uri[] grantedUriPermissions,
            int grantedMode, ActivityInfo aInfo, IBinder resultTo,
            String resultWho, int requestCode,
            int callingPid, int callingUid, boolean onlyIfNeeded,
            boolean componentSpecified, ActivityRecord[] outActivity) 

 

 if (mMainStack) {
            if (mResumedActivity == null
                    || mResumedActivity.info.applicationInfo.uid != callingUid) {
                if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
                    PendingActivityLaunch pal = new PendingActivityLaunch();
                    pal.r = r;
                    pal.sourceRecord = sourceRecord;
                    pal.grantedUriPermissions = grantedUriPermissions;
                    pal.grantedMode = grantedMode;
                    pal.onlyIfNeeded = onlyIfNeeded;
                    mService.mPendingActivityLaunches.add(pal);
                    mDismissKeyguardOnNextActivity = false;
                    return START_SWITCHES_CANCELED;
                }
            }
        
            if (mService.mDidAppSwitch) {
                // This is the second allowed switch since we stopped switches,
                // so now just generally allow switches.  Use case: user presses
                // home (switches disabled, switch to home, mDidAppSwitch now true);
                // user taps a home icon (coming from home so allowed, we hit here
                // and now allow anyone to switch again).
                mService.mAppSwitchesAllowedTime = 0;
            } else {
                mService.mDidAppSwitch = true;
            }
         
            mService.doPendingActivityLaunchesLocked(false);
        }
        
        err = startActivityUncheckedLocked(r, sourceRecord,
                grantedUriPermissions, grantedMode, onlyIfNeeded, true);
        if (mDismissKeyguardOnNextActivity && mPausingActivity == null) {
            // Someone asked to have the keyguard dismissed on the next
            // activity start, but we are not actually doing an activity
            // switch...  just dismiss the keyguard now, because we
            // probably want to see whatever is behind it.
            mDismissKeyguardOnNextActivity = false;
            mService.mWindowManager.dismissKeyguard();
        }

 进程启动的方法

 

private final void startProcessLocked(ProcessRecord app,
            String hostingType, String hostingNameStr) {
        if (app.pid > 0 && app.pid != MY_PID) {
            synchronized (mPidsSelfLocked) {
                mPidsSelfLocked.remove(app.pid);
                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
            }
            app.pid = 0;
        }

        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
                "startProcessLocked removing on hold: " + app);
        mProcessesOnHold.remove(app);

        updateCpuStats();
        
        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
        mProcDeaths[0] = 0;
        
        try {
            int uid = app.info.uid;
            int[] gids = null;
            try {
                gids = mContext.getPackageManager().getPackageGids(
                        app.info.packageName);
            } catch (PackageManager.NameNotFoundException e) {
                Slog.w(TAG, "Unable to retrieve gids", e);
            }
            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
                        && mTopComponent != null
                        && app.processName.equals(mTopComponent.getPackageName())) {
                    uid = 0;
                }
                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
                    uid = 0;
                }
            }
            int debugFlags = 0;
            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
                // Also turn on CheckJNI for debuggable apps. It's quite
                // awkward to turn on otherwise.
                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
            }
            // Run the app in safe mode if its manifest requests so or the
            // system is booted in safe mode.
            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
                Zygote.systemInSafeMode == true) {
                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
            }
            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
            }
            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
            }
            if ("1".equals(SystemProperties.get("debug.assert"))) {
                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
            }

            // Start the process.  It will either succeed and return a result containing
            // the PID of the new process, or else throw a RuntimeException.
            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
                    app.processName, uid, uid, gids, debugFlags,
                    app.info.targetSdkVersion, null);

            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
            synchronized (bs) {
                if (bs.isOnBattery()) {
                    app.batteryStats.incStartsLocked();
                }
            }
            
            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
                    app.processName, hostingType,
                    hostingNameStr != null ? hostingNameStr : "");
            
            if (app.persistent) {
                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
            }
            
            StringBuilder buf = mStringBuilder;
            buf.setLength(0);
            buf.append("Start proc ");
            buf.append(app.processName);
            buf.append(" for ");
            buf.append(hostingType);
            if (hostingNameStr != null) {
                buf.append(" ");
                buf.append(hostingNameStr);
            }
            buf.append(": pid=");
            buf.append(startResult.pid);
            buf.append(" uid=");
            buf.append(uid);
            buf.append(" gids={");
            if (gids != null) {
                for (int gi=0; gi<gids.length; gi++) {
                    if (gi != 0) buf.append(", ");
                    buf.append(gids[gi]);

                }
            }
            buf.append("}");
            Slog.i(TAG, buf.toString());
            app.pid = startResult.pid;
            app.usingWrapper = startResult.usingWrapper;
            app.removed = false;
            synchronized (mPidsSelfLocked) {
                this.mPidsSelfLocked.put(startResult.pid, app);
                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                msg.obj = app;
                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
            }
        } catch (RuntimeException e) {
            // XXX do better error recovery.
            app.pid = 0;
            Slog.e(TAG, "Failure starting process " + app.processName, e);
        }
    }

 Process.java

 

    public static final ProcessStartResult start(final String processClass,
                                  final String niceName,
                                  int uid, int gid, int[] gids,
                                  int debugFlags, int targetSdkVersion,
                                  String[] zygoteArgs) {
        try {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    debugFlags, targetSdkVersion, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
            throw new RuntimeException(
                    "Starting VM process through Zygote failed", ex);
        }
    }

 

分享到:
评论

相关推荐

    Activity和Service生命周期及使用AIDL通信实例备份

    Activity的生命周期分为几个关键状态:创建(onCreate())、启动(onStart())、可见(onResume())、暂停(onPause())、停止(onStop())、销毁(onDestroy())。理解这些状态及其转换对于优化性能和处理内存管理...

    Activity多页面跳转 比例布局 单多选框使用

    首先,我们来谈谈Activity的跳转。在Android中,我们使用Intent对象来启动一个新的Activity。Intent是一种消息传递对象,它可以包含启动Activity所需的数据。创建Intent有两种方式:显式Intent和隐式Intent。显式...

    Android Activity之间的跳转以及数据的交互传递

    例如,要启动名为`TargetActivity`的新Activity,可以在当前Activity中写入以下代码: ```java Intent intent = new Intent(this, TargetActivity.class); startActivity(intent); ``` 此外,Intent还支持通过...

    activity 一些小东西哦

    首先,我们来谈谈Android `Activity`的生命周期。一个`Activity`从创建到销毁经历了一系列的状态变化,这些状态包括:`onCreate()`(创建)、`onStart()`(可见)、`onResume()`(前台活动)、`onPause()`(暂停)、...

    activity onResume的理解,跨应用广播

    当一个Activity被启动或者从不可见状态恢复到可见状态时,`onResume()`会被调用。这个过程可能因为用户按了Home键、接到了电话或者打开了一个新的Activity而中断,但一旦用户返回,`onResume()`将再次被调用,确保...

    activity demo例子

    接下来,让我们谈谈Activity的部署。在Android开发中,部署通常是指将应用打包成APK文件并安装到设备上。这可以通过Android Studio的Build菜单中的Generate Signed Bundle / APK选项来完成。生成签名的APK后,可以...

    Activity和Fragment之间相互传值和调用方法

    最后,我们来谈谈回退栈(BackStack)。在Activity与Fragment交互中,回退栈管理着Fragment的添加、替换和移除。当用户点击返回按钮时,系统会按照回退栈的顺序恢复或移除Fragment。了解如何正确地管理回退栈,能够...

    3.6Activity的生命周期以及Fragment-new - 副本

    1. **创建状态(Created)**:当Activity首次启动或者由于系统原因重新创建时,会调用`onCreate()`方法。在这个阶段,开发者通常会进行布局加载、初始化组件、设置数据绑定等工作。 2. **启动状态(Started)**:`...

    谈谈Android里的Context的使用

    其实我们应用启动的时候会启动Application这个类,这个类是在AndroidManifest.xml文件里其实是默认的 android:icon="@drawable/ic_launcher" android:label="@string/app_name" &gt; &lt;activity android:name...

    Android项目冷启动优化——欢迎页

    2. **优化启动Activity**:启动Activity是冷启动的第一步,尽量保持其简洁,避免在启动时执行耗时操作,如网络请求、大数据量的图片加载等。可以考虑使用SplashActivity作为启动页面,专门用于处理启动时的优化工作...

    谈谈Android Fragments 详细使用

    fragments 的设计不需要你来亲自管理view hierarchy 的复杂变化,通过将Activity 的布局分散到frament 中,可以在运行时修改activity 的外观,并且由activity 管理的back stack 中保存些变化。 Fragment

    Activity2Activity_Communication

    `putExtra()`方法是Intent类的一个成员,用于添加额外的数据到Intent中,以便在启动目标Activity时能够访问这些数据。例如,我们可以传递基本类型(如int、String等)以及Parcelable或Serializable接口实现的对象。 ...

    android PopupWindow 和 Activity弹出窗口实现方式

    接下来,我们谈谈使用Activity作为弹出窗口的方式。这种方式通常适用于需要一个全屏或者半屏的独立界面,且包含复杂交互的情况。例如,登录窗口、设置界面等。创建一个新Activity,并在主题中设置透明背景,就可以...

    tabhost和ActivityGroup的组合使用

    3. 添加和替换内部Activity:使用LocalActivityManager的startActivity()和replaceId()方法来启动和替换内部Activity。这两个方法会自动处理Activity的压栈和出栈操作。 虽然ActivityGroup在新的Android版本中已...

    android使用service和activity获取屏幕尺寸的方法

    了解了如何在`Activity`和`Service`中获取屏幕尺寸后,我们再谈谈Android组件之间的通信。在Android中,`Activity`和`Service`之间的通信通常有以下几种方式: 1. ** Binder **:通过实现`IBinder`接口,`Service`...

    Android实现过渡动画、引导页 Android判断是否第一次启动App

    将包含过渡动画的Activity设置为默认启动的Activity,然后在`onCreate()`方法中调用`postDelayed()`,将延时时间设置为两秒,这样在启动时会等待两秒后执行后续操作。以下是一个简单的过渡页面布局示例: ```xml ...

    跳转和动画

    当用户需要从一个Activity移动到另一个Activity时,开发者会使用Intent对象来指定目标Activity,并调用startActivity()方法来启动这个过程。Intent不仅可以用来启动Activity,还可以用于启动服务或广播接收器,但在...

    Android_进程任务线程[参照].pdf

    Task就像一个堆栈,新启动的Activity会被压入栈顶,成为当前活动的Activity,而用户可以通过返回操作移除栈顶的Activity,使栈底的Activity成为当前活动。Task通常与应用的前台运行状态相对应,用户看到的是一个整体...

    显式和隐式、过滤器intent的使用

    例如,当你需要从一个Activity启动另一个Activity时,你会使用显式Intent,并指定目标Activity的ComponentName。 ```java Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivity...

Global site tag (gtag.js) - Google Analytics