<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
當一個Activity進入了停止狀態,是有可能被系統回收的。想象以下場景:應用中有一個ActivityA,使用者在ActivityA的基礎上啟動了ActivityB,ActivityA就進入了停止狀態,這個時候由於系統記憶體不足,將ActivityA回收掉了,然後使用者按下Back鍵返回ActivityA,會出現什麼情況呢?其實還是會正常顯示ActivityA的,只不過這時並不會執行onRestart()方法,而是會執行ActivityA的onCreate()方法,因為ActivityA在這種情況下會被重新建立一次。
但是這種情況下可能會出現一個重要的問題:ActivityA中是可能存在臨時資料和狀態的。打個比方,MainActivity中如果有一個文字輸入框,現在你輸入了一段文字,然後啟動NormalActivity,這時MainActivity由於系統記憶體不足被回收掉,過了一會你又點選了Back鍵回到MainActivity,這個時候你會發現剛剛輸入的文字都沒了,因為MainActivity被重新建立了。
如果我們的應用出現了這種情況是比較影響使用者體驗的,其實Activity還提供了一個onSaveInstanceState()回撥方法,這個方法可以保證在Activity被回收之前一定會被呼叫,因此我們可以通過這個方法來解決這個問題。
onSaveInstanceState()方法會攜帶一個Bundle型別的引數,Bundle提供了一系列的方法儲存資料,比如可以使用putString()方法儲存字串,使用putInt()方法儲存整型資料,以此類推。每個儲存方法需要傳入兩個引數,第一個引數是鍵,用於後面從Bundle中取值,第二個引數是真正要儲存的內容。
在MainActivity中新增如下程式碼就可以將臨時資料進行儲存了:
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) val tempData="Something you just typed" outState.putString("data_key",tempData) }
資料是已經儲存下來了,那麼我們應該在哪裡進行恢復呢?其實我們一直在使用的onCreate()方法其實也有一個Bundle型別的引數。這個引數在一般情況下都是null,但是如果在Activity被系統回收之前,你通過onSaveInstanceState()方法儲存資料,這個引數就會帶有之前儲存的全部資料,我們只需要再通過相應的取值方法將資料取出即可。
修改MainActivity的onCreate()方法,如下所示:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_first) if(savedInstanceState!=null){ val tempData = savedInstanceState.getString("data_key") tempData?.let { Log.d("tag", it) } } }
取出值之後就可以再做相應的恢復操作就可以了,比如將文字內容重新賦值到文字輸入框上,這裡我只是簡單列印一下。
這裡使用Bundle儲存和取出資料和我們之前使用Intent傳遞資料的方法很類似,首先我們可以把需要傳遞的資料都儲存在Bundle物件中,然後再將Bundle物件存放在Intent裡。到了目標Activity之後,先從Intent中取出Bundle,再從Bundle中一一取出資料。
另外在手機的螢幕發生旋轉的時候,Activity也會經歷一個重新建立的過程,因而在這種情況下,Activity中的資料也會丟失。這種問題也可以通過onSaveInstanceState()方法來解決,但是對於橫豎屏已經有了更好的方案。
使用 ViewModel,我們就無需再用這種方法儲存,因為 ViewModel 會自動感知生命週期,處理資料的儲存與恢復。即資料可在發生螢幕旋轉等設定(其它例如解析度調整、許可權變更、系統字型樣式、語言變更等)更改後繼續留存。
程式碼如下:
package com.example.viewmodeldemo; import androidx.appcompat.app.AppCompatActivity; import androidx.lifecycle.ViewModelProvider; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private MyViewModel mMyViewModel; private TextView textView; private Button mButton1; private Button mButton2; private final String TAG="MainActivityTest"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "onCreate: "); //建立一個ViewModel物件 mMyViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class); textView=findViewById(R.id.textView); //ViewModel會儲存資料,當你重新建立的時候會載入顯示出來 textView.setText(String.valueOf(mMyViewModel.number)); mButton1=findViewById(R.id.button1); mButton2=findViewById(R.id.button2); mButton1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mMyViewModel.number++; textView.setText(String.valueOf(mMyViewModel.number)); } }); mButton2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mMyViewModel.number+=2; textView.setText(String.valueOf(mMyViewModel.number)); } }); } @Override protected void onStart() { super.onStart(); Log.d(TAG, "onStart: "); } @Override protected void onStop() { super.onStop(); Log.d(TAG, "onStop: "); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy: "); } @Override protected void onPause() { super.onPause(); Log.d(TAG, "onPause: "); } @Override protected void onResume() { super.onResume(); Log.d(TAG, "onResume: "); } }
package com.example.viewmodeldemo; import androidx.lifecycle.ViewModel; //這裡的ViewModel可以看作全域性變數倉庫 public class MyViewModel extends ViewModel { public int number=0; }
這樣當你旋轉螢幕生命週期發生變化,你的資料還在。
到此這篇關於Android Activity被回收的情況分析的文章就介紹到這了,更多相關Android Activity被回收內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45