不调用onNewIntent

时间:2014-05-03 15:07:01

标签: 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);
}

这里的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);
    }   
}

我没有看到"我工作"不幸的是,在我的日志中。
我在SO和互联网上都阅读了很多类似的问题,尝试设置Intent标志SINGLE_TOP,SINGLE_TASK等。

这是Android Manifest of 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>

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

编辑:我已尝试过所有内容:SINGLE_TOP,SINGLE_INSTANCE,SINGLE_TASK ..
但后来我偶尔会在另一项活动中这样做:

Main m = new Main();
m.onNewIntent(this.getIntent());

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

7 个答案:

答案 0 :(得分:63)

<强>序言

好吧,我对这个问题迟到了,但是当我偶然发现同样的问题而没有答案或其他四个stackoverflow问题时,我发现这个问题,为我解决了问题,这是我想出来的。

<强>解答:

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

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

      

    ...当在活动堆栈顶部重新启动活动而不是正在启动的活动的新实例时,onNewIntent()将在具有Intent的现有实例上被调用用来重新启动它。&#34;

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

    • 根据我的理解,调用onCreate或onNewIntent,但从不同时调用。
    • 因此,如果您想通过Intent将数据传递给活动,并且它应该始终有效(如我的情况),无论活动是重新启动还是活动是新创建的,您都可以按照{{ 3}}。
    • 作为上述博客文章中描述的解决方案的变体,您还可以利用这样一个事实,即无论是否调用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
      }
      

      对于此示例,getIntent将始终为您提供用于startActivity调用或Notification的Intent,因为如果Activity是新创建的(因此调用了onCreate),也将为Activity设置新的Intent。 / p>

  4. <强> POSTAMBLE:

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

答案 1 :(得分:20)

您想要在onNewIntent()上接收的活动应该

android:launchMode="singleTop"

或添加标志tn intent

browserInt.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                    Intent.FLAG_ACTIVITY_SINGLE_TOP);

onNewIntent(Intent)

中所述

答案 2 :(得分:8)

以下是可能会让您感到困惑的一种情况,以及更多信息:使用此代码按预期调用onNewIntent

Intent intent = new Intent...
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
finish();
startActivity(intent);

但没有使用此代码

Intent intent = new Intent...
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
finish();

原因在于,在第二个代码块中,在为当前活动调用finish之前添加了新活动,因此要使第二个代码块起作用,必须添加FLAG_ACTIVITY_CLEAR_TOP标志正如其他一些答案所建议的那样:

Intent intent = new Intent...
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

请注意,此处未调用finish,因为它是为您调用的。来自documentation for the FLAG_ACTIVITY_CLEAR_TOP flag

  

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

答案 3 :(得分:3)

我在Android中使用onNewIntent进行搜索实施。当我在模拟器中使用键盘上的Go按钮时,我遇到了onNewIntent未被调用的问题。我通过在onCreate方法中放置处理意图的代码解决了这个问题。需要这样做以确保在启动活动的新实例时处理意图操作。

这就产生了一个问题,因为只要活动从之前的状态恢复,就会调用onCreate。因此,即使发生方向改变,也会调用意图处理方法。

解决方案:使用if (savedInstanceState==null)确定活动是从之前的状态恢复还是新搜索。

答案 4 :(得分:1)

使用onNewIntent处理singleTop的最佳方法就是:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}

然后在getIntent内的onResume上完成所有逻辑。

答案 5 :(得分:0)

对我来说,我没有在清单中的活动中添加搜索操作:

<activity android:name=".SearchResultsActivity" ... >
    ...
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    ...
</activity>

在此处检查您的步骤: https://developer.android.com/training/search/setup

答案 6 :(得分:-2)

要进入onNewIntent方法,您需要在AndroidManifest.xml文件中,在将主活动设置为启动模式后放置,在此启动模式中您必须放置singleInstance,例如:

<activity 
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:launchMode="singleInstance"
        android:windowSoftInputMode="adjustPan" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

现在您可以使用NewIntent方法输入。