实例计数违规在Android的Java应用程序 [英] Instance count violation in an Android Java app

查看:337
本文介绍了实例计数违规在Android的Java应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个Android应用程序。在抽象的,这种应用具有用户界面,以与用户进行交互,它也与远程服务进行交互。远程服务添加到Android启动栏通知,该通知允许重新显示UI。该应用程序和服务都在同一个包。服务通知功能的code:

 私人无效showNotification(字符串contentText){
    意向意图=新意图(这一点,my_app.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
    的PendingIntent的PendingIntent = PendingIntent.getActivity(
            对此,0,意向,PendingIntent.FLAG_UPDATE_CURRENT);
    mNotification =新Notification.Builder(本)
    .setContentIntent(的PendingIntent)
    .setSmallIcon(ICON)
    .setWhen(System.currentTimeMillis的())
    .setContentTitle(CONTENT_TITLE)
    .setContentText(contentText)
    .setAutoCancel(假)
    .setOngoing(真)
    。建立();
    mNotificationManager.notify(NOTIFICATION_ID,mNotification);
}

请注意:这是法的最新版本... previously我也试过以下标志

  intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
   intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
   intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);

应用程序的清单包含以下配置:

 <应用
    机器人:图标=@绘制/图标
    机器人:标签=@字符串/ APP_NAME
    机器人:allowBackup =真
    机器人:launchMode =singleTop
    机器人:uiOptions =splitActionBarWhenNarrow
    机器人:allowTaskReparenting =真正的> ...< /用途>

注:我也尝试过其他礼节但这些预期不会做影响...

在应用程序启动,但它没有更多的显示,可以重新显示其使用启动栏的通知或使用应用程序列表应用程序的入口,但是当我执行下面的情况下,显示两次的用户界面:


  1. 从启动列表中的应用程序

  2. 磁带上的主页按钮

  3. (重新)显示使用的通知应用程序
    ==> UI正确地重新显示

  4. 磁带上的主页按钮

  5. (重新)使用应用程序列表显示应用程序
    ==>显示UI的新实例

情况的日志:

 从应用程序列表#START
I / ActivityManager(504):开始U0 {行为= android.intent.action.MAIN猫= [android.intent.category.LAUNCHER] FLG = 0x10200000 CMP = com.domain.my_app / .My_App bnds = [40833] [200 ,1033]}从PID 871
I / my_app应用(6915)的onCreate
I / my_app应用::服务(6930):的onCreate
I / my_app应用(6915):onResume
#tape home键
I / my_app应用(6915)的onPause
从启动栏通知#restart
I / ActivityManager(504):从PID启动U0 {FLG = 0x34400000 CMP = com.domain.my_app / .My_App bnds = [0102] [720230]} -1
I / my_app应用(6915):onResume
#tape home键
I / my_app应用(6915)的onPause
从应用程序列表#START
I / ActivityManager(504):开始U0 {行为= android.intent.action.MAIN猫= [android.intent.category.LAUNCHER] FLG = 0x10200000 CMP = com.domain.my_app / .My_App bnds = [40833] [200 ,1033]}从PID 871
I / my_app应用(6915)的onCreate
I / my_app应用(6915):onResume
#tape home键
I / my_app应用(6915)的onPause
从启动栏通知#restart
I / ActivityManager(504):从PID启动U0 {FLG = 0x34400000 CMP = com.domain.my_app / .My_App bnds = [0102] [720230]} -1
I / PSI记录仪(6915):onResume
#it​​需要使用两次my_app应用退出按钮以退出该应用程序,然后在日志中,我注意到以下错误
E / StrictMode(6915):类com.domain.my_app;实例= 2;极限= 1
E / StrictMode(6915):android.os.StrictMode $ InstanceCountViolation:类com.domain.my_app;实例= 2;极限= 1

我读了很多东西,提示等有关应用程序,远程服务和通知,但我无法理解为什么当应用程序从列表重新启动UI重新创建,且仅当previously,这是从通知重新显示...
注意:如果FLAG_ACTIVITY_NEW_TASK标志没有被加入到意图,以下警告被记录,并且不改变所观察到的行为...

  W / ActivityManager(504):startActivity非活动上下文中调用;迫使Intent.FLAG_ACTIVITY_NEW_TASK为:意向{FLG = 0x24400000 CMP = com.domain.my_app / .My_App bnds = [0102] [720230]}

我将AP preciate任何帮助。

感谢您。
最好的问候,

编辑:这是我的错,而不是应用程序清单领域,机器人:launchMode =singleTop属性,应该在活动元素:/

我感动,它的工作原理

 <应用
    机器人:图标=@绘制/图标
    机器人:标签=@字符串/ APP_NAME
    机器人:allowBackup =真正的>
    <活动
        机器人:my_app应用NAME =
        机器人:configChanges =方向
        机器人:标签=@字符串/ APP_NAME
        机器人:launchMode =singleTop


解决方案

我觉得问题的根源是你的意图标志的组合。为了帮助调试这个问题,尝试实施<一个href=\"http://developer.android.com/reference/android/app/Activity.html#onNewIntent%28android.content.Intent%29\"相对=nofollow> onNewIntent()在您的活动的方法,并记录每次收到,像这样的意图:

 保护无效onNewIntent(意向意图){
    super.onNewIntent(意向);
    Log.i(my_app应用+ intent.getFlags与旗新意图());
}

这应该让你看到国旗在你的日志造成的onCreate()的第二个电话。

对于StrictMode实例数侵犯,我不认为这是值得研究的解释<一个href=\"http://stackoverflow.com/questions/5956132/android-strictmode-instancecountviolation\">here.

修改
尝试仅使用旗Intent.FLAG_ACTIVITY_NEW_TASK,例如,删除其他三个标志。同时,保留了android:launchMode到singleTop

I am working on an Android application. In abstract, this application has an UI in order to interact with user and it also interacts with a remote service. The remote service adds a notification to Android launcher bar and this notification allows to redisplay the UI. The app and the service are in same package. The code of service notification function:

private void showNotification (String contentText) {
    Intent intent = new Intent (this, my_app.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
    PendingIntent pendingIntent = PendingIntent.getActivity(
            this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    mNotification = new Notification.Builder(this)
    .setContentIntent(pendingIntent)
    .setSmallIcon(ICON)
    .setWhen(System.currentTimeMillis())
    .setContentTitle(CONTENT_TITLE)
    .setContentText(contentText)
    .setAutoCancel(false)
    .setOngoing(true)
    .build();
    mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}

Note: it is current version of method... previously I also tried the following FLAGS

   intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
   intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
   intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);

The manifest of application contains the following configuration:

    <application
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:allowBackup="true"
    android:launchMode="singleTop"
    android:uiOptions="splitActionBarWhenNarrow"
    android:allowTaskReparenting="true">...</application>

Note: I tried also other proprieties but these do not expected impact...

When the application is started but it is no more displayed, it is possible to redisplay its using notification of launcher bar or using the application entry in "Applications list" but when I execute the following scenario, the UI is displayed twice:

  1. start the application from list
  2. tape on home button
  3. (re)display the application using notification ==> UI is correctly redisplayed
  4. tape on home button
  5. (re)display the application using "applications list" ==> a new instance of UI is displayed

The logs of scenario:

#start from applications list
I/ActivityManager(  504): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.domain.my_app/.My_App bnds=[40,833][200,1033]} from pid 871
I/my_app( 6915): onCreate
I/my_app::Service( 6930): onCreate
I/my_app( 6915): onResume
#tape the home button
I/my_app( 6915): onPause
#restart from notification in launcher bar
I/ActivityManager(  504): START u0 {flg=0x34400000 cmp=com.domain.my_app/.My_App bnds=[0,102][720,230]} from pid -1
I/my_app( 6915): onResume
#tape the home button
I/my_app( 6915): onPause
#start from application list
I/ActivityManager(  504): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.domain.my_app/.My_App bnds=[40,833][200,1033]} from pid 871
I/my_app( 6915): onCreate
I/my_app( 6915): onResume
#tape the home button
I/my_app( 6915): onPause
#restart from notification in launcher bar
I/ActivityManager(  504): START u0 {flg=0x34400000 cmp=com.domain.my_app/.My_App bnds=[0,102][720,230]} from pid -1
I/PSI Recorder( 6915): onResume
#it is necessary to use two times the my_app quit button in order to exit the application, and then in log, I noted the following error
E/StrictMode( 6915): class com.domain.my_app; instances=2; limit=1
E/StrictMode( 6915): android.os.StrictMode$InstanceCountViolation: class com.domain.my_app; instances=2; limit=1

I read a lot of things, tips, etc. about application, remote service and notification but I am unable to understand why the UI is recreated when the application is restarted from list, and only if previously, it was redisplayed from notification... Note: if the FLAG_ACTIVITY_NEW_TASK flag is not added to intent, the following warning is logged, and it does not change the observed behaviour...

W/ActivityManager(  504): startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: Intent { flg=0x24400000 cmp=com.domain.my_app/.My_App bnds=[0,102][720,230] }

I will appreciate any help.

Thank you. Best regards,

EDIT: It is my fault, instead of "application" Manifest field, the android:launchMode="singleTop" attribute should be in "activity" element :/

I moved and it works

    <application
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:allowBackup="true">
    <activity
        android:name=".my_app"
        android:configChanges="orientation"
        android:label="@string/app_name"
        android:launchMode="singleTop"

解决方案

I think the source of the problem is your combination of intent flags. To help you debug this, try to implement the onNewIntent() method in your activity, and log every intent it receives, with something like this:

protected void onNewIntent(Intent intent){
    super.onNewIntent(intent);
    Log.i("my_app", "New intent with flags "+intent.getFlags());
}

This should allow you to see what flags are causing the second call to onCreate() in your logs.

As for the StrictMode instance count violation, I don't think it is worth investigating as explained here.

EDIT Try to use only the flag Intent.FLAG_ACTIVITY_NEW_TASK, e.g., remove the other three flags. Also, keep the android:launchMode to singleTop.

这篇关于实例计数违规在Android的Java应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆