Android设备是否有任何理由可以启动具有相同名称,相同用户ID和不同PID的应用程序的新流程,并保持旧设备仍处于活动状态?
清单未指定除默认进程以外的任何其他进程。
旧进程可以通过终端中的kill命令终止。
在某些已定义的情况下,这是预期的行为还是Android错误?
清单看起来像这样:
<?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>
更新:我设法获得了一些日志记录。我的应用程序有一个名为UpdateContentReceiver
的Receiver(上面更新的清单),每隔一分钟调用一次UPDATE_CONTENT
意图,从主消息队列发布。它进行一些网络轮询和完成。它曾经工作......
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
......但下次......
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}
最后一行清楚地表明创建了一个新流程。之后,我在日志中看到MyApplication
使用不同的PID启动了三次,直到它与最后一个进程一起生效。这是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
我不能说TransactionTooLargeException
为什么会发生(我们只发送UPDATE_CONTENT
没有额外内容,所以内存占用很少),但至少我知道为什么要创建一个新进程。仍然不清楚为什么旧的过程不会被破坏。该应用程序有一个内部Web服务器:也许Android看到侦听TCP端口并拒绝杀死它?
有趣的是,新进程无法运行自己的Web服务器(因为侦听端口已经绑定),但是一切都“有效”,因为旧的Web服务器仍然存在!
答案 0 :(得分:0)
指的是:Re-launch of Activity on Home button, but...only the first time 或者:How to prevent multiple instances of an activity when it is launched with different intents
您可以将应用定义为:android:launchMode="singleInstance"
但我选择:
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;
}
}
编辑:(等待问题中的清单)
<强>机器人:多进程强> 是否可以将活动的实例启动到启动它的组件的进程中 - 如果可以,则为“true”,否则为“false”。默认值为“false”。
通常,活动的新实例会启动到定义它的应用程序的进程中,因此所有实例都会被启动 活动在同一个过程中运行。但是,如果此标志设置为 “true”,活动的实例可以在多个进程中运行, 允许系统在任何地方创建实例 (提供权限允许),几乎从不 必要或可取的。
来源:https://developer.android.com/guide/topics/manifest/activity-element.html