【问题标题】:onNewIntent is not calledonNewIntent 没有被调用
【发布时间】:2014-05-03 15:07:01
【问题描述】:

我的情况很奇怪。
有了一个应用程序,我决定从第一个应用程序的代码中创建另一个应用程序。
我复制了 .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);
    }   
}

很遗憾,我的日志中没有看到“I WORKED”。
我在 SO 和 Internet 上阅读了很多类似的问题,尝试设置 Intent 标志 SINGLE_TOP、SINGLE_TASK 等。

这是 WORKING 项目的 Android 清单:

<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());

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

【问题讨论】:

  • 当然它直接“工作”,但是从构造函数创建一个 Activity 将永远不会返回指向将要显示的 Activity 的指针。

标签: android android-intent


【解决方案1】:

序言:

好吧,我对此有点晚了,但是由于我偶然发现了同样的问题,并且这里没有答案或其他四个 stackoverflow 问题中的任何一个,我找到了这个问题,为我解决了这个问题,这里是我发现了什么。

回答:

有几个可能的原因,为什么 onNewIntent 没有被调用,我将把它们都列出来——好吧,我都知道。

  1. 正如之前的许多答案和 onNewIntent 函数的文档中所提到的(雅罗斯拉夫答案中的链接),您要么需要活动的 android:launchMode="singleTop" 清单条目,您希望在其中调用 onNewIntent,要么需要用于开始活动必须有标志FLAG_ACTIVITY_SINGLE_TOP。您不需要两者(它是| 又名。逻辑or 不是&amp; 又名。逻辑and)!还应该为android:launchMode="singleTask" 调用 onNewIntent,但在使用它之前,最好先查看 android:launchMode 文档,因为它的后果远不止一个函数调用。
  2. 在旧版本的 Android 中有一个 bug,它基本上阻止了 android:launchMode="singleTop" 按规定工作,因此无法调用 onNewIntent。该错误从未正式解决,但我无法在版本 4.4.2(Samsung S4 Mini)中重现它。所以它似乎在 4.0.x 和 4.4.2 之间的某个时间点被修复了。
  3. 并非每次满足前面提到的先决条件时,都会调用 onNewIntent。正如函数的文档所述:

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

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

    • 据我了解,onCreate 或 onNewIntent 都会被调用,但绝不会同时调用两者。
    • 因此,如果您想通过 Intent 将数据传递给活动并且它应该始终有效(如我的情况),无论活动是重新启动还是新创建活动,您都可以按照@987654322 中的说明进行操作@。
    • 作为上述博客文章中描述的解决方案的变体,您还可以利用以下事实,即无论是否调用 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 调用或通知的 Intent,因为如果 Activity 是新创建的(因此调用了 onCreate),也会为 Activity 设置新的 Intent。

POSTAMBLE:

抱歉,帖子太长了。我希望你能从中找到一些有用的东西。

【讨论】:

  • 处理同一问题的问题:182095283256633130708462
  • setIntent(intent); 确实帮助我将意图传递给相应的片段。谢谢
  • tldr;) 您需要在onCreate()onNewIntent() 中处理您的意图,因为如果目标顶级活动未运行,则不会调用onNewIntent()
  • 请注意,Android 5 需要 FLAG_ACTIVITY_NEW_TASK,否则 FLAG_ACTIVITY_SINGLE_TOP 将不会调用 onNewIntent()
  • 另外值得注意的是,正如我发现的那样,根据您的上下文,当您执行不同的任务时,可能没有方便的方法来重用现有活动。例如。从应用 A 中的活动启动应用 B 中的活动时。虽然您可以使用 allowTaskReparenting 活动元素来帮助解决此问题,但我无法让它为我工作,因为我需要手动设置 @ 987654343@ 来创建 reparenting 工作所需的关联,我不想强​​制执行此操作,因为应用 A 实际上是使用我们 SDK 的第三方应用...
【解决方案2】:

你想要接收 onNewIntent() 的 Activity 应该有

android:launchMode="singleTop"

或者添加flag tn intent

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

onNewIntent(Intent) 中所述

【讨论】:

  • 这没有帮助。但我最终找到了解决方案
  • @Kondra007 解决方案是什么。
  • 解决方法似乎可以在编辑的问题中找到
【解决方案3】:

这里有一种情况可能会影响您,以及更多信息: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();

这样做的原因是,在第二个代码块中,新活动是在为当前活动调用完成之前添加到顶部的,因此要使第二个代码块工作,您必须按照建议添加 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

如果设置了,并且正在启动的 Activity 已经在当前任务中运行,那么不会启动该 Activity 的新实例,而是关闭它之上的所有其他 Activity,并且此 Intent 将被传递到(现在在顶部)作为新 Intent 的旧活动。

【讨论】:

    【解决方案4】:

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

    这带来了一个问题,因为每当活动从以前的状态恢复时都会调用onCreate。因此,即使发生方向更改,也会调用意图处理方法。

    解决方案:使用if (savedInstanceState==null) 确定活动是否正在从以前的状态恢复,或者是新的搜索。

    【讨论】:

      【解决方案5】:

      singleTop 处理onNewIntent 的最佳方式就是这样:

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

      然后在onResume 内部的getIntent 上执行所有逻辑。

      【讨论】:

      • 我的 onNewIntent() 永远不会被调用,你能和我分享一些关于这个的想法吗?
      • 我实际上不确定这是在回答这个问题。出于某种原因,我认为问题是从活动内部获得新的意图。相反,我认为问题是“为什么没有 onNewIntent 被调用?”我认为@Yaroslav Mytkalyk 的帖子是最正确的。确保您使用单顶。 (并且可能它是一个新的意图,不等于已经启动该活动的任何意图。)
      【解决方案6】:

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

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

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

      【讨论】:

        【解决方案7】:

        要进入 onNewIntent 方法,你需要在你的 AndroidManifest.xml 文件中,在设置你的主要活动之后放一个启动模式,在这个启动模式下你必须放单实例例如:

        <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>
        

        现在您可以输入 onNewIntent 方法了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-10-21
          • 1970-01-01
          • 2021-09-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多