不调用onNewIntent

29 android android-intent

我的情况很奇怪.
有一个应用程序,我决定从第一个应用程序的代码创建另一个.
我复制了.xml文件,复制了.java文件以便一切正常.
但是有一个巨大的问题:我的onNewIntent(Intent intent)方法是在第一个项目中调用的,但它没有在第二个项目中调用(代码是相同的!)

方法,可以触发,但现在无法触发

public void onClick(View arg0) {
    Intent browserInt = new Intent (Intent.ACTION_VIEW, 
    Uri.parse("https://oauth.yandex.ru/authorize?response_type=token&client_id=zzzzz"));
    browserInt.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(browserInt);
}
Run Code Online (Sandbox Code Playgroud)

这是onNewIntent()方法:

@Override
protected void onNewIntent(Intent intent){
    System.out.println(" I WORKED!");
    Uri uri = intent.getData();
    if (uri!=null) {
        String m = uri.toString().split("#")[1];
        String[] args = m.split("&");
        String arg = args[0];
        String token = arg.split("=")[1];
        System.out.println(token);
    }   
}
Run Code Online (Sandbox Code Playgroud)

遗憾的是,我在日志中看不到"我工作".
我在SO和Internet上都阅读了很多类似的问题,尝试设置Intent标志SINGLE_TOP,SINGLE_TASK等等.

这是Android Manifest的WORKING项目:

<application 
    android:name="yyy"
    android:icon="@drawable/yaru_icon"
    android:allowBackup="false"
    android:label="xxx"
    android:theme="@style/LightTheme">

    <activity
        android:name=".Main"
        android:label="xxx"
        android:launchMode="singleTask">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
</application>
Run Code Online (Sandbox Code Playgroud)

我非常绝望,为什么类似的代码不再起作用了?

编辑:我已经尝试了一切:SINGLE_TOP,SINGLE_INSTANCE,SINGLE_TASK ..
但后来我偶尔在另一个活动上做了这个:

Main m = new Main();
m.onNewIntent(this.getIntent());
Run Code Online (Sandbox Code Playgroud)

它终于奏效了!
我不知道,无论是肮脏的解决方法还是错误,如果有人能够解释它,请评论.

小智 72

前言:

好吧,我对这个问题有点晚了,但是当我偶然发现同样的问题并且没有回答或者其他四个stackoverflow问题时,我找到了这个问题,为我解决了问题,这就是我想的出.

回答:

有几个可能的原因,为什么onNewIntent没有被调用,我将列出所有 - 我知道所有这些.

  1. 正如前和文档的onNewIntent功能(在Yaroslavs答案链接)在许多答案中提到,您可能需要android:launchMode="singleTop"为活动,您要onNewIntent被称为用于启动活动必须具有清单项,或意图国旗FLAG_ACTIVITY_SINGLE_TOP.你不需要两者(这|不是一个or;-))!也应该调用onNewIntent &,但在使用它之前,最好检查一下android:launchMode文档,因为它比一个函数调用有更多的后果.
  2. 在旧版本的Android中,存在一个错误,它基本上无法and按指定的方式工作,从而无法调用onNewIntent.该错误从未正式解决,但我无法在版本4.4.2(三星S4迷你)中重现它.所以它似乎已经在4.0.x和4.4.2之间的某个点固定.
  3. 并非每次满足前面提到的前提条件时,都会调用onNewIntent.作为函数的文档说明:

    ...当在活动堆栈的顶部重新启动活动而不是正在启动的活动的新实例时,将在现有实例上调用onNewIntent(),并使用用于重新启动它的Intent ."

    这意味着,如果活动是新创建的,无论你设置了什么launchMode或Intent标志,都不会调用onNewIntent!

    • 根据我的理解,调用onCreate或onNewIntent,但从不同时调用.
    • 所以,如果你想通过Intent将数据传递给活动,它应该始终有效(就像我的情况一样),无论活动是重新启动还是新创建的活动,你都可以按照这个非常有用的博客文章中所描述的那样做.
    • 作为上述博客文章中描述的解决方案的变体,您还可以利用这样一个事实:无论是否调用onNewIntent或onCreate,onResume将始终被调用,并执行以下操作:

      @Override
      protected void onNewIntent(Intent intent) {
          super.onNewIntent(intent);
          setIntent(intent);
      }
      
      @Override
      protected void onResume() {
          super.onResume();
          Intent intent = getIntent();
          // ... do what you wanna do with the intent
      }
      
      Run Code Online (Sandbox Code Playgroud)

      在这个例子中getIntent将永远得到你用于startActivity来电或通知的意图,作为新的意向也将在活动中设置,如果该活动是新创建(并因此的onCreate叫).

POSTAMBLE:

对不起,很长的帖子.我希望你能找到一些有用的东西.


Yar*_*lyk 20

您希望在NewIntent()中接收的活动应具有

android:launchMode="singleTop"
Run Code Online (Sandbox Code Playgroud)

或者添加标志tn intent

browserInt.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                    Intent.FLAG_ACTIVITY_SINGLE_TOP);
Run Code Online (Sandbox Code Playgroud)

onNewIntent(Intent)中所述

  • @ Kondra007是什么解决方案. (52认同)
  • 那没有帮助。但我最终找到了解决方案 (2认同)

Nat*_*ook 8

这里有一种情况可能会咬你,还有更多的信息:onNewIntent用这段代码按预期调用:

Intent intent = new Intent...
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
finish();
startActivity(intent);
Run Code Online (Sandbox Code Playgroud)

但不是这个代码

Intent intent = new Intent...
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
finish();
Run Code Online (Sandbox Code Playgroud)

原因在于,在第二个代码块中,在为当前活动调用完成之前添加了新活动,因此为了使第二个代码块起作用,您必须FLAG_ACTIVITY_CLEAR_TOP按照其他一些答案的建议添加标记, 像这样:

Intent intent = new Intent...
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Run Code Online (Sandbox Code Playgroud)

请注意,finish这里根本没有调用,因为它是为您调用的.从FLAG_ACTIVITY_CLEAR_TOP标志文档:

如果已设置,并且正在启动的活动已在当前任务中运行,则不会启动该活动的新实例,而是将关闭其上的所有其他活动,并将此Intent传递给(现在开启) top)旧活动作为新的意图.