簡體   English   中英

onNewIntent 沒有被調用

[英]onNewIntent is not called

我的情況很奇怪。
有了一個應用程序,我決定從第一個應用程序的代碼中創建另一個應用程序。
我復制了.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 和 Internet 上閱讀了很多類似的問題,嘗試設置 Intent 標志 SINGLE_TOP、SINGLE_TASK 等。

這是工作項目的 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());

它終於奏效了!
我不知道這是一個骯臟的解決方法還是一個錯誤,如果有人可以解釋它,請發表評論。

前言:

好吧,我對這個問題有點晚了,但是當我偶然發現同樣的問題並且在這里或其他四個 stackoverflow 問題中的任何一個都沒有答案時,我找到了這個問題,為我解決了這個問題,這就是我的想法出去。

回答:

有幾個可能的原因,為什么沒有調用 onNewIntent,我將列出所有這些 - 我知道所有這些。

  1. 正如之前和 onNewIntent 函數的文檔中提到的許多答案(Yaroslavs 答案中的鏈接),您需要android:launchMode="singleTop"活動清單條目,您希望在其中調用 onNewIntent,或者使用 Intent開始活動必須有標志FLAG_ACTIVITY_SINGLE_TOP 你不需要兩者(它是| aka.logical or not a & aka.logical and )! 也應該為android:launchMode="singleTask"調用android:launchMode="singleTask" ,但在使用之前,您最好查看 android:launchMode 文檔,因為它具有更多的后果,而不僅僅是一個函數調用。
  2. 在舊版本的 Android 中有一個錯誤,它基本上阻止了android:launchMode="singleTop"按指定工作,因此無法調用 onNewIntent。 該錯誤從未正式解決,但我無法在版本 4.4.2(Samsung S4 Mini)中重現它。 所以它似乎已在 4.0.x 和 4.4.2 之間的某個時間點得到修復。
  3. 並非每次滿足前面提到的先決條件時,都會調用 onNewIntent。 正如該函數的文檔所述:

    ...當活動在活動堆棧的頂部重新啟動而不是啟動活動的新實例時,將在現有實例上調用 onNewIntent() 並使用用於重新啟動它的 Intent .

    這意味着,如果活動是新創建的,則不會調用 onNewIntent,無論您設置了什么 launchMode 或 Intent 標志!

    • 據我了解,onCreate 或 onNewIntent 都被調用,但永遠不會同時調用。
    • 因此,如果您想通過 Intent 將數據傳遞給 Activity 並且它應該始終有效(就像我的情況一樣),無論是重新啟動 Activity 還是新創建的 Activity,您都可以按照這篇非常有用的博客文章中的描述進行操作.
    • 作為上述博客文章中描述的解決方案的變體,您還可以利用這樣一個事實,即無論是調用 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。

后文:

抱歉,帖子太長了。 我希望你能從中找到有用的東西。

您想要接收 onNewIntent() 的 Activity 應該有

android:launchMode="singleTop"

或添加標志 tn 意圖

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

onNewIntent(Intent) 中所述

以下是一種可能會讓您onNewIntent的情況,以及更多信息:使用以下代碼按預期調用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第二個代碼塊工作,您必須按照其他一些人的建議添加FLAG_ACTIVITY_CLEAR_TOP標志答案,像這樣:

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

請注意,這里根本沒有調用finish ,因為它是為您調用的。 FLAG_ACTIVITY_CLEAR_TOP 標志文檔中

如果設置,並且正在啟動的活動已經在當前任務中運行,那么不是啟動該活動的新實例,而是將關閉它之上的所有其他活動,並且此 Intent 將被傳遞到(現在在頂部)舊活動作為新意圖。

我在 Android 中使用onNewIntent進行搜索實現。 我遇到了在模擬器中使用鍵盤上的 Go 按鈕時沒有調用onNewIntent的問題。 我通過在onCreate方法中放置處理意圖的代碼解決了這個問題。 需要這樣做以確保在啟動活動的新實例時處理意圖操作。

這帶來了一個問題,因為只要活動從先前的狀態恢復,就會調用onCreate 因此,即使發生方向更改,也會調用意圖處理方法。

解決方案:使用if (savedInstanceState==null)來確定活動是否正在從以前的狀態恢復,或者是新搜索。

使用singleTop處理onNewIntent的最佳方法很簡單:

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

然后在onResume內的getIntent上執行所有邏輯。

對我來說,我沒有向清單中的活動添加搜索操作:

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

在此處檢查您的步驟: https : //developer.android.com/training/search/setup

在我的例子中,我只是在AndroidManifest文件的活動標簽中添加launchMode="singleInstance"

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleInstance">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

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

注意:我使用的是 kotlin。

要進入 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>

現在您將能夠輸入您的 onNewIntent 方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM