Android-後臺運行的Activity回到前臺(onNewIntent()會替代onCreat()方法)

在Android應用程序開發的時候,從一個Activity啓動另一個Activity並傳遞一些數據到新的Activity上非常簡單
但是當您需要讓後臺運行的Activity回到前臺並傳遞一些數據可能就會存在一點點小問題。

1.首先,在默認情況下,當您通過Intent啓到一個Activity的時候,就算已經存在一個相同的正在運行的Activity,系統都會創建一個新的Activity實例並顯示出來。
爲了不讓Activity實例化多次,我們需要通過在AndroidManifest.xml配置activity的加載方式(launchMode)以實現單任務模式
參照:Activity的四種啓動模式http://blog.csdn.net/cl18652469346/article/details/53672136

注:也可以通過Intent.FLAG_ACTIVITY_SINGLE_TOP標誌啓動Activity,效果跟android:launchmode=”singleTask”一樣

2.launchMode爲singleTask的時候,通過Intent啓到一個Activity,
如果系統已經存在一個實例,系統就會將請求發送到這個實例上,
但這個時候,系統就不會再調用通常情況下我們處理請求數據的onCreate方法,而是調用onNewIntent方法

protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);//must store the new intent unless getIntent() will return the old one
    processExtraData();
}

PS:
系統可能會隨時殺掉後臺運行的Activity,如果這一切發生,那麼系統就會調用onCreate方法,而不調用onNewIntent方法,
一個好的解決方法就是在onCreate和onNewIntent方法中調用同一個處理數據的方法

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    processExtraData();
}

protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);//must store the new intent unless getIntent() will return the old one
    processExtraData()
}

private void processExtraData(){
    Intent intent = getIntent();
    //use the data received here
}

In a word : 當從棧中啓動一個已經存在的Activity時,系統不會再執行onCreate方法,而是執行onNewIntent方法

簡單的介紹兩個例子:

實例1:Android 監聽home鍵(android:launchMode=”singleTask” 與 onNewIntent(Intent intent) 的用法
它們兩結合使用,可以做到監聽home鍵(僅當發起新的Intent)。

代碼如下:

AndroidManifest.xml
<activity android:name = ".OnNewIntentDemo"  
    android:launchMode = "singleTask"
    android:label = "@string/app_name" >
    < intent-filter >
        <action android:name = "android.intent.action.MAIN" />
        <category android:name = "android.intent.category.LAUNCHER" />
        </intent-filter >
        <intent-filter >
        <action android:name = "android.intent.action.VIEW" />
        <category android:name = "android.intent.category.DEFAULT" />
        <data android:mimeType = "video/*" />
    </ intent-filter >
</ activity >


Activity中代碼
@Override  
protected void onNewIntent(Intent intent) {
    if (DEBUG) Log.i(TAG, "onNewIntent ~~~~~~~ intent = " +intent);
    super .onNewIntent(intent);
}

實例2:發通知 PendingIntent中Intent內容沒有更新[延時意圖]
AndroidManifest.xml代碼
android:launchMode=”singleTask” />
當我們把Activity 啓動模式設置爲 singleTask 之後 當我們下次再去用Intent啓動這個 Activity 的時候 就不會去調用 onCreate方法 而是去調用onNewIntent()方法 然後把Intent中的數據傳給它 , 前幾天遇到的問題是 當我 發一個通知給狀態欄 然後點擊這個通知 自然會執行 PendingIntent 裏邊的Intent。 但是 在Activity那邊的 onNewIntent()方法裏邊 得到的數據 不是最新的 也就是說 是 第一次的 以後 不管我怎麼點通知 它都 是 第一次點擊通知得到的數據,當以後再點擊通知的時候其實 數據已經變了 但是 onNewIntent()方法總是得不到最新的數據, 無語了很久, 去 農民伯伯翻譯組 發問得解 需要給 PendingIntent 加一個 FLAG

Java代碼
PendingIntent contentIntentBegin = PendingIntent.getActivity(
notificationContext, 0, inStart, PendingIntent.FLAG_UPDATE_CURRENT);

最後一個參數就是 FLAG,這個FLAG 的 意思就是:
如果系統中已存在該PendingIntent對象,那麼系統將保留該PendingIntent對象,但是會使用新的Intent來更新之前PendingIntent中的Intent對象數據,
例如更新Intent中的Extras。這個非常有用,
例如之前提到的,我們需要在每次更新之後更新Intent中的Extras數據,達到在不同時機傳遞給MainActivity不同的參數,實現不同的效果。
就是 Intent裏邊的數據沒更新而已, 很2個問題 搞了很久 才發現原來加個FLAG 就行了,有點傷不起了。!!

代碼片段

Java代碼
public void showNotiMessageBegin(String message, int requestCode,String itemid) {
    notification = new Notification(R.drawable.skyfile_upload_noti,message, System.currentTimeMillis());
    if (requestCode == 1 && notification.contentIntent == null) {
        int index = itemid.lastIndexOf("/");
        final String backPath1 = itemid.substring(0, index == 0 ? 1 : index);
        Intent inStart = new Intent(notificationContext, SkyfileActivity.class);
        inStart.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        inStart.setData(Uri.parse(MetaDataView.class.getName()));
        inStart.putExtra(MetaDataView.BUNDLE_PATH, backPath1);
        PendingIntent contentIntentBegin = PendingIntent.getActivity(notificationContext, 0, inStart, PendingIntent.FLAG_UPDATE_CURRENT);
        notification.contentIntent = contentIntentBegin;
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        notification.setLatestEventInfo(notificationContext,
        UPLOATTITLE, message, contentIntentBegin);
        notificationMgr.notify(1, notification);
    } else {
        notification.contentIntent.cancel();
    }
}
發佈了116 篇原創文章 · 獲贊 26 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章