代码之家  ›  专栏  ›  技术社区  ›  Rich

安卓“单顶”启动模式和onNewIntent方法

  •  43
  • Rich  · 技术社区  · 16 年前

    我在Android文档中读到,通过将活动的launchMode属性设置为singleTop或添加 FLAG_ACTIVITY_SINGLE_TOP 这是我的意图,这是我的使命 startActivity(intent) 将重用单个活动实例,并在 onNewIntent 回拨。我做了这两件事 奥涅温特 永远不要开火和射击 onCreate 每次都开火。文件还说 this.getIntent() 创建时的回调函数 我打电话来 getIntent

    为了增加一些背景信息,以防我只是缺少了一个必需的步骤,下面是清单中的活动声明和我用来启动活动的代码。在这方面,活动本身没有做任何值得一提的事情:

        <activity
            android:name=".ArtistActivity"
            android:label="Artist"
            android:launchMode="singleTop">
        </activity>     
    

    在我的呼叫活动中:

            Intent i = new Intent();
            i.putExtra(EXTRA_KEY_ARTIST, id);
            i.setClass(this, ArtistActivity.class);
            i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
            startActivity(i);
    
    3 回复  |  直到 16 年前
        1
  •  38
  •   znq    16 年前

    你查过了吗 onDestroy() onCreate() 每次调用,而不是 onNewIntent()

    例如,如果您通过“后退”按钮退出活动,则默认情况下会将其销毁。但是如果你在活动堆栈中的位置更高,进入其他活动,并从那里调用你的 ArtistActivity.class onCreate() 直接去 onNewIntent() ,因为活动已经创建,并且您将其定义为 singleTop Android不会创建一个新的实例,但以已经存在的实例为例。

    我所做的是为了了解发生了什么,我为每个活动的所有不同状态实现了虚拟函数,所以我现在总是知道发生了什么:

    @Override
    public void onDestroy() {
        Log.i(TAG, "onDestroy()");
        super.onDestroy();
    }
    

    onRestart() , onStart() onResume() , onPause() , onDestroy()

    如果上面的(后退按钮)不是您的问题,那么实现这些假人至少可以帮助您更好地调试它。

        2
  •  33
  •   Steve B    10 年前

    这种说法是错误的 :

    中的“单顶”部分 http://developer.android.com/guide/components/tasks-and-back-stack.html 清楚地解释它是如何工作的(注意下面的粗体文本;我也通过自己的调试证明了这一点):

    堆栈是A-B-C-D;D在上面 ). 类型为D的活动的意图到达。如果D具有默认的“标准”启动模式,则会启动该类的新实例,堆栈将变为a-B-C-D-D。但是,如果D的启动模式为“singleTop”,则D的现有实例将通过onNewIntent()接收意图,因为它位于堆栈的顶部,堆栈将保持A-B-C-D。然而, 如果类型为B的活动的意图到达,则会将B的新实例添加到堆栈中,即使其启动模式为“singleTop”

    换句话说,通过SINGLE_TOP启动活动只会重用现有活动(如果它是 已经在堆栈的顶部 . 如果同一任务中的另一个活动位于顶部(例如,正在执行startActivity(SINGLE_top)的活动),则它将不起作用;将创建一个新实例。

    有两种方法可以解决这个问题 这样你就可以得到你想要的单一行为——其一般目的是重用现有的活动,而不是创建一个新的活动。。。

    第一条路 (如接受合同评论部分所述)

    第二种方式(更好): 使用FLAG_ACTIVITY_REORDER_TO_FRONT代替FLAG_ACTIVITY_SINGLE_TOP。这将通过将现有活动实例移动到堆栈顶部来重用它(将按预期调用onNewIntent()。

    FLAG_ACTIVITY_SINGLE_TOP的主要目的是防止创建一个活动的多个实例。例如,当该活动可以通过来自应用程序主任务之外的意图启动时。对于在我的应用程序中的活动之间进行内部切换,我发现通常我想要的是将活动重新排序到前台。

        3
  •  3
  •   林果皞    8 年前

    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP)