這篇文章要記錄onSaveInstanceState以及onRestoreInstanceState的使用,小蛙其實對這個部分了解還不是很透徹,但是小蛙的做法的確是可以work,供大家做個參考囉!

照照明星臉上架以來直到現在(好慚愧),一直無法擺脫拍完照片,或是從相簿選取圖片後無法使用的情況(有些是Force Close, 有些是直接跳回主畫面沒有任何反應),這裡面的問題有很多,是小蛙一開始不太能夠完全掌握相機及相簿的使用造成的,後來慢慢的大部分的機種都可以正常使用,卻面臨到同樣機種的手機,有些可以正常使用,有些卻無法使用,例如:HTC Sensation有使用者回報正常使用,卻也有回報無法使用 … 同樣的最近小蛙面臨到的是 SE Arc S。

小蛙的同事昨天跟小蛙說,他的Arc S沒有辦法使用明星臉,跟上面敘述的是一樣的問題,小蛙借了他的Arc S測試後發現,拍照前建立的tmpFile以及傳給相機的imageUri,在最後onActivityResult回來後全部都變成null,小蛙百思不得其解啊!為什麼回到主畫面之後會變成null,直到看到這篇stackoverflow的文章,文章的標題雖然看起來沒關係,但jeffamaphone的回應幫了小蛙大忙!

onSaveInstanceState跟onRestoreInstanceState的官方說明如下(截錄自Activity | Android Developers):

protected void onSaveInstanceState (Bundle outState)

Called to retrieve per-instance state from an activity before being killed so that the state can be restored in onCreate(Bundle) or onRestoreInstanceState(Bundle) (the Bundle populated by this method will be passed to both).

This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state. For example, if activity B is launched in front of activity A, and at some point activity A is killed to reclaim resources, activity A will have a chance to save the current state of its user interface via this method so that when the user returns to activity A, the state of the user interface can be restored via onCreate(Bundle) or onRestoreInstanceState(Bundle).

Do not confuse this method with activity lifecycle callbacks such as onPause(), which is always called when an activity is being placed in the background or on its way to destruction, or onStop() which is called before destruction. One example of when onPause() and onStop() is called and not this method is when a user navigates back from activity B to activity A: there is no need to call onSaveInstanceState(Bundle) on B because that particular instance will never be restored, so the system avoids calling it. An example when onPause() is called and not onSaveInstanceState(Bundle) is when activity B is launched in front of activity A: the system may avoid calling onSaveInstanceState(Bundle) on activity A if it isn’t killed during the lifetime of B since the state of the user interface of A will stay intact.

The default implementation takes care of most of the UI per-instance state for you by calling onSaveInstanceState() on each view in the hierarchy that has an id, and by saving the id of the currently focused view (all of which is restored by the default implementation of onRestoreInstanceState(Bundle)). If you override this method to save additional information not captured by each individual view, you will likely want to call through to the default implementation, otherwise be prepared to save all of the state of each view yourself.

If called, this method will occur before onStop(). There are no guarantees about whether it will occur before or after onPause().

protected void onRestoreInstanceState (Bundle savedInstanceState)

This method is called after onStart() when the activity is being re-initialized from a previously saved state, given here in savedInstanceState. Most implementations will simply use onCreate(Bundle) to restore their state, but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation. The default implementation of this method performs a restore of any view state that had previously been frozen by onSaveInstanceState(Bundle).

This method is called between onStart() and onPostCreate(Bundle).

看得懂的就看,看不懂的google一下,對岸有很多網站對於這兩個function都有翻譯。小蛙這邊直接講照照明星臉相機及相簿無法使用的原因。

點選從使用相機拍照及從相簿選擇的同時,小蛙先建了一個tmpFile,在丟入相機的參數中增加imageUri = Uri.fromFile(tmpFile);,正常情況下若從相簿挑選照片回來,小蛙會把得到的相片轉存到tmpFile(如此是為了避免修改或刪除原始照片);假設從相機回來,可以從剛剛設定的imageUri中取得圖片,但偏偏這兩個回來的東西在一台Arc S上面正常,在另一台Arc S上面卻回傳java.lang.NullPointerException。

Override了onSaveInstanceState及onRestoreInstanceState這兩個function印出Log訊息發現,兩台都會呼叫onSaveInstanceState,但是只有其中一台會呼叫onRestoreInstanceState,而這台恰巧就是會發生錯誤的那台。小蛙猜測當使用Intent開啟內建相機時(MediaStore.ACTION_IMAGE_CAPTURE),由於手機內部的記憶體不夠使用,造成照照明星臉主程式必須先暫時關閉,當照相動作完成後才會再回到照照明星臉,這時候照照明星臉之前建立的變數,例如:tmpFile, imageUri。就會變成null解決的方法只要在Override onSaveInstanceState並且在該function中加入要保存的變數及其值,當主控權又回到照照明星臉時再呼叫onRestoreInstanceState把剛剛存起來的值還原,就可以避免掉onActivityResult()中有時候會出現java.lang.NullPointerException,有時候卻又可以正常使用的問題了!

相關文章

Android Vuforia with jPCT-AE (5) – 多重模型載入,以 obj 為例

要進到這系列最後一篇文章了,這篇文章拖了很久,一直沒有時間整理,結果到最後 ... 程式碼留下來了,記憶卻有些模糊了,這邊小蛙配著程式碼盡可能的把還記得的東西寫下來。
2016-07-06 11:24:19
hans

8

Android Vuforia with jPCT-AE (4) – 載入 3DS 測試

延續 jPCT-AE Loader 載入模型的部份,這篇要記錄載入 3ds 檔案格式的方法,基本上跟前面幾個 obj, md2 的方法差不多,只有一些小小的變化而已。
2016-07-06 10:24:33
hans

8

Android Vuforia with jPCT-AE (3) – 載入 md2 測試

前兩篇介紹如何直接透過 jPCT-AE 直接繪圖以及載入 .obj 檔案,這邊繼續介紹 jPCT-AE 載入 md2 的方法,載入動作大致上類似,唯一不同的只有 texture 設定部份。
2016-07-06 09:24:43
hans

8

Android Vuforia with jPCT-AE (2) – 載入 obj 測試

上一篇 Android Vuforia with jPCT-AE (1) –
2016-07-06 08:24:55
hans

8

Android Vuforia with jPCT-AE (1) – 基本範例

說來慚愧,從 Google Adsense 被 ban 之後,就好久沒有發文了,站上 Vuforia 的文章也已經是好久以前的事情了 (遠目),最近有專案要用到 Vuforia,爬以前的文回來看,蛙哩咧 ... 現在已經更新到 Vu
2016-07-06 07:57:58
hans

8

ClickForce (MobiForce) 當機問題

這真是個浪費時間又漫長的過程,CF 推出新版後台以及新版 SDK 的時候,小蛙就下載來測試,一開始小蛙直接套在「我的股票精算師」上,但只要一套上去就當機 ...
2015-09-02 10:32:51
hans

8

Qualcomm Vuforia 教學 (6) – 3D model -> .obj -> .h

終於來到 Vuforia 記錄的最後一篇了,這篇參考到網路上神人的做法,怎麼把一個 3D model 轉換成 Vuforia 可以使用的 .h 檔,這邊之後都直接使用 An
2014-12-10 11:25:50
hans

8

Qualcomm Vuforia 教學 (4) – 使用 Android NDK 版本並開啟多重偵測

接續前幾篇教學,我們已經建置好 Vuforia 開發及執行環境
2014-12-09 17:10:57
hans

8

Qualcomm Vuforia 教學 (1) – 安裝 Vuforia

工作上有使用 AR: Augmented Reality
2014-12-08 18:08:50
hans

8




 回覆

你可以使用以下語法 HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="">

(required)

(required)

   
© 2012 蛙齋 Suffusion theme by Sayontan Sinha