Android6.0 AMS启动Activity(五) 在新进程中启动Activity



前面我们在分析Activity启动过程的时候,看到同一个应用程序的Activity一般都是在同一个进程中启动,事实上,Activity也可以像Service一样在新的进程中启动,这样,一个应用程序就可以跨越好几个进程了,本文就分析一下在新的进程中启动Activity的方法和过程。

        在Android系统中,每一个应用程序都是由一些Activity和Service组成的,一般Service运行在独立的进程中,而Activity有可能运行在同一个进程中,也有可能运行在不同的进程中。在前面我们已经介绍了Android应用程序在Launcher桌面启动一个Activity需要启动一个进程,也介绍了在进程内部启动Activity过程(startActivity)。而现在,我们就来看一下同一个Android应用程序如何在新的进程中启动新的Activity。


要做到这个其实很简单,只需要在AndroidManifest.xml中将主Activity和要启动的Activity的android:process属性设置为不同的

<?xml version="1.0" encoding="utf-8"?>      
<manifest xmlns:android="http://schemas.android.com/apk/res/android"      
    package="shy.luo.task"      
    android:versionCode="1"      
    android:versionName="1.0">      
    <application android:icon="@drawable/icon" android:label="@string/app_name">      
        <activity android:name=".MainActivity"      
                  android:label="@string/app_name">    
                  android:process=":com.example.process.main"    
            <intent-filter>      
                <action android:name="android.intent.action.MAIN" />      
                <category android:name="android.intent.category.LAUNCHER" />      
            </intent-filter>      
        </activity>      
        <activity android:name=".SubActivity"      
                  android:label="@string/sub_activity"    
                  android:process=":shy.luo.process.sub">      
            <intent-filter>      
                <action android:name="com.example.process.subactivity"/>      
                <category android:name="android.intent.category.DEFAULT"/>      
            </intent-filter>      
        </activity>      
    </application>      
</manifest>    

同一个应用程序的Activity组件都是运行在同一个进程中,但是,如果Activity配置了android:process这个属性,那么,它就会运行在自己的进程中。如果android:process属性的值以":"开头,则表示这个进程是私有的;如果android:process属性的值以小写字母开头,则表示这是一个全局进程,允许其它应用程序组件也在这个进程中运行。

        因此,这里我们以":"开头,表示创建的是私有的进程。事实上,这里我们不要前面的":"也是可以的,但是必须保证这个属性性字符串内至少有一个"."字符。

具体解析AndroidManifest.xml会在安装apk的时候在PKMS调用PackageParser的parseBaseApplication来解析。具体代码我们会在后续博客(专门讲PKMS安装apk)中再分析。

这样processName不一样之后,在AMS启动一个Activity时开启一个进程。当再启动一个Activity的时候,因为processName不一样,发现没有进程的processName是这个name。所以就要再起一个进程,具体代码我们之前博客也分析过,是在ActivityStackSupervisor的startSpecificActivityLocked函数中,发现没有这个processName的进程后。会调用mService.startProcessLocked函数重启启动一个进程,也会新建一个ProcessRecord保存这个进程的信息。

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


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 VB6.0 检测当前程序是否在开机启动的完整代码示例: ``` Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, ByRef phkResult As Long) As Long Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, ByRef lpType As Long, ByVal lpData As String, ByRef lpcbData As Long) As Long Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long Const HKEY_CURRENT_USER = &H80000001 Const KEY_READ = &H20019 Private Sub Form_Load() ' 获取当前程序的可执行文件名 Dim exeName As String exeName = App.Path & "\" & App.EXEName & ".exe" ' 打开注册表项 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run Dim hKey As Long Dim ret As Long ret = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\Microsoft\Windows\CurrentVersion\Run", 0, KEY_READ, hKey) If ret <> 0 Then MsgBox "打开注册表项失败!" Exit Sub End If ' 检查注册表项是否存在当前程序的键值 Dim valueData As String Dim valueType As Long Dim valueSize As Long valueData = Space$(1024) valueSize = Len(valueData) ret = RegQueryValueEx(hKey, App.Title, 0, valueType, valueData, valueSize) RegCloseKey hKey If ret = 0 Then MsgBox "程序已经在开机启动。" Else MsgBox "程序未加入开机启动项。" End If End Sub ``` 在运行该程序时,它将检查当前程序是否在开机启动,并在窗体显示相应的提示信息。需要注意的是,该程序需要以管理员权限运行,否则无法打开注册表项。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值