Two Android apps with the same name, why?

Is there a reason why an Android device can start a new process with the same name, with the same user ID and a different PID, and keep the old one?

The manifest does not specify any other processes than the standard one.

The old process can be killed with the kill command in the terminal.

Is this the expected behavior in some specific cases, or is this an Android bug?

the manifest looks like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mycompany.myapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="19" />

    <!-- omitted <uses-permission> tags -->

    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:hardwareAccelerated="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" >

        <!-- Start up -->
        <activity
            android:name=".activity.SplashScreenActivity"
            android:configChanges="orientation|keyboardHidden" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- other non-launcher activities... -->

        <!-- Auto start on boot -->
        <receiver android:name=".receiver.StartEventsReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

        <!-- Update content and configuration -->
        <receiver
            android:name=".receiver.UpdateContentReceiver"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.mycompany.myapp.UPDATE_CONTENT" />
                <action android:name="com.mycompany.myapp.CONTENT_UPDATED" />
            </intent-filter>
        </receiver>
        <!-- other receivers and services... -->

    </application>

</manifest>

      

UPDATE . I managed to get some records. My app has a receiver called UpdateContentReceiver

(manifest above updated) that gets called every minute with intent UPDATE_CONTENT

sent from the main message queue. It does some polling and exits the network. He worked...

08-30 09:46:57.419  2512  2512 V UpdateContentReceiver: Received UPDATE_CONTENT
08-30 09:46:58.349  2512  2512 V UpdateContentReceiver: No update

08-30 09:47:57.439  2512  2512 V UpdateContentReceiver: Received UPDATE_CONTENT
08-30 09:47:57.739  2512  2512 V UpdateContentReceiver: No update

08-30 09:48:57.439  2512  2512 V UpdateContentReceiver: Received UPDATE_CONTENT
08-30 09:49:02.389  2512  2512 V UpdateContentReceiver: No update

      

... but next time ...

08-30 09:49:57.459  1879  1904 E JavaBinder: !!! FAILED BINDER TRANSACTION !!!
08-30 09:49:57.469  1879  1904 W BroadcastQueue: Exception when sending broadcast to ComponentInfo{com.mycompany.myapp/com.mycompany.myapp.receiver.UpdateContentReceiver}
08-30 09:49:57.469  1879  1904 W BroadcastQueue: android.os.TransactionTooLargeException
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at android.os.BinderProxy.transact(Native Method)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at android.app.ApplicationThreadProxy.scheduleReceiver(ApplicationThreadNative.java:771)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at com.android.server.am.BroadcastQueue.processCurBroadcastLocked(BroadcastQueue.java:231)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:778)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at com.android.server.am.BroadcastQueue$1.handleMessage(BroadcastQueue.java:140)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at android.os.Handler.dispatchMessage(Handler.java:99)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at android.os.Looper.loop(Looper.java:137)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at com.android.server.am.ActivityManagerService$AThread.run(ActivityManagerService.java:1487)
08-30 09:49:57.469  1879  1904 W ActivityManagerService: Scheduling restart of crashed service com.mycompany.myapp/.service.ServiceFoo in 5000ms
08-30 09:49:57.469  1879  1904 W ActivityManagerService: Scheduling restart of crashed service com.mycompany.myapp/.service.ServiceBar in 14999ms
08-30 09:49:57.469  1879  1904 W ActivityManagerServiceActivityStack_hong: Force removing ActivityRecord{42768bf8 u0 com.mycompany.myapp/.activity.MyActivity}: app died, no saved state
08-30 09:49:57.529  1879  1904 I ActivityManagerService: Start proc com.mycompany.myapp for broadcast com.mycompany.myapp/.receiver.UpdateContentReceiver: pid=27119 uid=10044 gids={50044, 3003, 1028, 1015, 1023}

      

The last line clearly states that a new process is being created. After that I see in the logs that it MyApplication

starts up three times with different PIDs until it settles with the last life process. Here's the output ps|grep myapp

:

u0_a44    2512  1286  755540 85548 ffffffff 4003fee4 S com.mycompany.myapp                                                                      
u0_a44    28541 1286  772220 79204 ffffffff 4003fee4 S com.mycompany.myapp

      

I can't tell you why this is happening TransactionTooLargeException

(we dispatch UPDATE_CONTENT

without any extra functions, so there is little memory space), but at least I know why the new process is being created. However, it is not clear why the old process is not destroyed. The app has an internal web server: maybe Android sees that it is listening on a TCP port and refuses to kill it?

The funny thing is that the new process doesn't start its own web server (because the listening port is already bound), but everything "works" because the old web server is still alive!

+3


source to share


1 answer


referencing this: Restarting the Activity at Home button, but ... just the first time or this: How to prevent multiple instances of an activity from being launched with different intents

you can define your application as: android:launchMode="singleInstance"

But I choose:

if (!isTaskRoot()) {
    final Intent intent = getIntent();
    final String intentAction = intent.getAction(); 
    if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
        Log.w(LOG_TAG, "Main Activity is not the root.  Finishing Main Activity instead of launching.");
        finish();
        return;       
    }
}

      



Edit: (awaiting the manifest in the question)

Android: Multiple Processes Is it possible to instantiate an action in the process of the component that started it - "true" if possible and "false" if not. The default is "false".

Typically, a new activity instance is launched in the application process that defined it, so all activity instances run in the same process. However, when this flag is set to "true", instances of an activity can run across multiple processes, allowing the system to instantiate where they are used (if permissions allow), which is almost never necessary or desirable.

source: https://developer.android.com/guide/topics/manifest/activity-element.html

0


source







All Articles