【问题标题】:Every Activity in Android is a Process,or One Application is one processAndroid中的每个Activity都是一个进程,或者一个应用程序是一个进程
【发布时间】:2011-09-22 00:37:30
【问题描述】:

在此页面http://androidapps.org.ua/androidintro_ipc.html 中,活动之间的意图切换被描述为进程间通信。现在我很困惑每个活动是android中的一个单独的进程还是应用程序中的所有活动都是一个进程。我使用以下方法检查了我的应用程序中所有活动和服务的进程 ID:

 int id = android.os.Process.myPid();
 System.out.println("Process id of Activity1 :"+id);

但它显示相同的进程 ID。 请回复。

【问题讨论】:

    标签: android process android-activity ipc


    【解决方案1】:

    您可以将意图发送到另一个应用程序,前提是它具有意图过滤器。

    所以是的,您应用程序中的所有活动都将在同一个进程中运行。

    例如:您可以向所有电子邮件应用程序发送通用意图。 Gmail 就是这样一个应用程序,它有一个意图过滤器,可以监听电子邮件的意图。这就是使用意图实现 IPC 的方式。

    【讨论】:

    • 所以如果场景是这样的:四个Application组件(Activity、Service、Content Provider、Broadcast Receiver)在一个进程下的不同线程中运行。 Activity的线程是主UI线程,如果其他线程有任何变化,必须通知主UI线程
    【解决方案2】:

    不,一个应用程序的活动不会在每个不同的进程上运行。实际上,即使是同一个开发者构建的不同应用程序(如果所有应用程序都使用同一个证书)也可以在同一个进程中运行!

    As the documentation says:

    应用程序模块化——Android 系统允许应用程序是 由相同的证书签名运行 在同一过程中,如果 应用程序如此请求,以便 系统将它们视为单个 应用。这样你就可以 在模块中部署您的应用程序, 并且用户可以更新每个 如果需要,可以独立模块。

    【讨论】:

    • 那么如果场景是这样的:四个Application组件(Activity、Service、Content Provider、Broadcast Receiver)在一个进程下运行在不同的线程中。 Activity的线程是主UI线程,如果其他线程有任何变化,必须通知主UI线程。
    • @Naba:“四个应用程序组件(活动、服务、内容提供者、广播接收器)在一个进程下的不同线程中运行”——不。有一个进程,但它们都共享主应用程序线程。
    【解决方案3】:
    All activities inside an application run in one process?
    

    这取决于应用程序清单中android:process 属性的值。

    如果清单中的Application/Activity标签没有定义android:process属性,默认情况下所有活动都将在单个进程中运行(进程名称将是清单中定义的包的名称)

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.so.test" android:versionCode="1" android:versionName="1.0">
        <uses-sdk android:minSdkVersion="8" />
    
        <application android:icon="@drawable/icon" android:label="@string/app_name">
            <activity android:name=".Activity1">
            </activity>
            <activity android:name=".Activity2">
            </activity>
            <activity android:name=".Activity3">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    

    在上述清单中,所有活动都在进程中运行com.so.test,adb shell 中的ps 命令输出:

    # ps
    app_39    668   33    84492  20672 ffffffff afd0c51c S com.so.test
    

    如果为 Activity 指定了android:process,则将使用相同的用户 ID 创建新进程,并且 Activity 在该进程中运行。

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.so.test" android:versionCode="1" android:versionName="1.0">
        <uses-sdk android:minSdkVersion="8" />
    
        <application android:icon="@drawable/icon" android:label="@string/app_name" 
         android:process="com.so.p1">
            <activity android:name=".Activity1">
            </activity>
            <activity android:name=".Activity2" android:process="com.so.p2">
            </activity>
            <activity android:name=".Activity3" android:process="com.so.p3">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    

    如果清单定义如上

    Activity1 runs in com.so.p1 process
    Activity2 runs in com.so.p2 process
    Activity3 runs in com.so.p3 process
    

    adb shell 中的 ps 输出

    # ps
    app_39    650   33    83192  20900 ffffffff afd0c51c S com.so.p1
    app_39    659   33    83188  20864 ffffffff afd0c51c S com.so.p2
    app_39    668   33    84492  20672 ffffffff afd0c51c S com.so.p3
    

    如果 Activity 需要在此清单中未定义的另一个进程中运行,则两个 APK 应使用相同的证书进行签名。

    【讨论】:

    • Activity1 在 com.so.p1 进程中运行 Activity2 在 com.so.p2 进程中运行 Activity3 在 com.so.p3 进程中运行 每个进程会在单独的 VM 中运行吗?它是如何封装到该应用程序中的?
    • 服务,广播怎么样,它们是在单独的进程中运行还是与活动相同(即3个进程)?
    • 请注意,本地广播在不同进程之间不起作用。
    【解决方案4】:

    您可以使用带有android:process 属性的Manifest 组件元素来使用[多处理][1] 应用程序方法。它适用于所有组件

    <application>
        <activity/>
        <service/>
        <receiver/>
        <provider/>
    </application> 
    

    此外,&lt;application&gt; 元素还支持android:process 属性,以设置适用于所有组件的默认值。

    默认情况下,component process name 是一个包名。它可以被&lt;application&gt;&lt;android component&gt;(the biggest priority) 元素覆盖

    请注意,每个应用进程都有自己的应用程序实例。因此,如果您定义自己的自定义应用程序类 (&lt;application android:name=".CustomApplication" ...&gt;),请准备好在每次创建新进程期间至少调用 Application.onCreate()

    JFYI,请注意 ContentProvider.onCreate() 在任何其他初始化(如 Application.onCreate() 等)之前被调用。为您的库获取 Context 可能会有所帮助,而无需来自开发端的额外代码

    要获取进程名称,您可以使用下一个方法

    @Nullable
    public static String getProcessName(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo processInfo : activityManager.getRunningAppProcesses()) {
            if (processInfo.pid == android.os.Process.myPid()) {
                return processInfo.processName;
            }
        }
        return null;
    }
    

    或通过Terminal输入adb shell ps | grep &lt;packagename&gt; [1]:https://developer.android.com/guide/components/processes-and-threads#Processes

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      • 2015-06-22
      • 2013-10-22
      • 2015-09-14
      • 1970-01-01
      • 1970-01-01
      • 2020-04-04
      相关资源
      最近更新 更多