欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android Activity被回收的情況分析

 更新時(shí)間:2022年11月24日 11:52:04   作者:發(fā)飆的蝸牛YR  
Activity作為Android四大組件之一,他的啟動(dòng)絕對(duì)沒有那么簡(jiǎn)單。這里涉及到了系統(tǒng)服務(wù)進(jìn)程,啟動(dòng)過程細(xì)節(jié)很多,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值

1.onSaveInstanceState()方法

當(dāng)一個(gè)Activity進(jìn)入了停止?fàn)顟B(tài),是有可能被系統(tǒng)回收的。想象以下場(chǎng)景:應(yīng)用中有一個(gè)ActivityA,用戶在ActivityA的基礎(chǔ)上啟動(dòng)了ActivityB,ActivityA就進(jìn)入了停止?fàn)顟B(tài),這個(gè)時(shí)候由于系統(tǒng)內(nèi)存不足,將ActivityA回收掉了,然后用戶按下Back鍵返回ActivityA,會(huì)出現(xiàn)什么情況呢?其實(shí)還是會(huì)正常顯示ActivityA的,只不過這時(shí)并不會(huì)執(zhí)行onRestart()方法,而是會(huì)執(zhí)行ActivityA的onCreate()方法,因?yàn)锳ctivityA在這種情況下會(huì)被重新創(chuàng)建一次。

但是這種情況下可能會(huì)出現(xiàn)一個(gè)重要的問題:ActivityA中是可能存在臨時(shí)數(shù)據(jù)和狀態(tài)的。打個(gè)比方,MainActivity中如果有一個(gè)文本輸入框,現(xiàn)在你輸入了一段文字,然后啟動(dòng)NormalActivity,這時(shí)MainActivity由于系統(tǒng)內(nèi)存不足被回收掉,過了一會(huì)你又點(diǎn)擊了Back鍵回到MainActivity,這個(gè)時(shí)候你會(huì)發(fā)現(xiàn)剛剛輸入的文字都沒了,因?yàn)镸ainActivity被重新創(chuàng)建了。

如果我們的應(yīng)用出現(xiàn)了這種情況是比較影響用戶體驗(yàn)的,其實(shí)Activity還提供了一個(gè)onSaveInstanceState()回調(diào)方法,這個(gè)方法可以保證在Activity被回收之前一定會(huì)被調(diào)用,因此我們可以通過這個(gè)方法來解決這個(gè)問題。

onSaveInstanceState()方法會(huì)攜帶一個(gè)Bundle類型的參數(shù),Bundle提供了一系列的方法保存數(shù)據(jù),比如可以使用putString()方法保存字符串,使用putInt()方法保存整型數(shù)據(jù),以此類推。每個(gè)保存方法需要傳入兩個(gè)參數(shù),第一個(gè)參數(shù)是鍵,用于后面從Bundle中取值,第二個(gè)參數(shù)是真正要保存的內(nèi)容。

在MainActivity中添加如下代碼就可以將臨時(shí)數(shù)據(jù)進(jìn)行保存了:

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        val tempData="Something you just typed"
        outState.putString("data_key",tempData)
    }

數(shù)據(jù)是已經(jīng)保存下來了,那么我們應(yīng)該在哪里進(jìn)行恢復(fù)呢?其實(shí)我們一直在使用的onCreate()方法其實(shí)也有一個(gè)Bundle類型的參數(shù)。這個(gè)參數(shù)在一般情況下都是null,但是如果在Activity被系統(tǒng)回收之前,你通過onSaveInstanceState()方法保存數(shù)據(jù),這個(gè)參數(shù)就會(huì)帶有之前保存的全部數(shù)據(jù),我們只需要再通過相應(yīng)的取值方法將數(shù)據(jù)取出即可。

修改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) }
        }
}

取出值之后就可以再做相應(yīng)的恢復(fù)操作就可以了,比如將文本內(nèi)容重新賦值到文本輸入框上,這里我只是簡(jiǎn)單打印一下。

這里使用Bundle保存和取出數(shù)據(jù)和我們之前使用Intent傳遞數(shù)據(jù)的方法很類似,首先我們可以把需要傳遞的數(shù)據(jù)都保存在Bundle對(duì)象中,然后再將Bundle對(duì)象存放在Intent里。到了目標(biāo)Activity之后,先從Intent中取出Bundle,再?gòu)腂undle中一一取出數(shù)據(jù)。

另外在手機(jī)的屏幕發(fā)生旋轉(zhuǎn)的時(shí)候,Activity也會(huì)經(jīng)歷一個(gè)重新創(chuàng)建的過程,因而在這種情況下,Activity中的數(shù)據(jù)也會(huì)丟失。這種問題也可以通過onSaveInstanceState()方法來解決,但是對(duì)于橫豎屏已經(jīng)有了更好的方案。

2.ViewModel

使用 ViewModel,我們就無(wú)需再用這種方法保存,因?yàn)?ViewModel 會(huì)自動(dòng)感知生命周期,處理數(shù)據(jù)的保存與恢復(fù)。即數(shù)據(jù)可在發(fā)生屏幕旋轉(zhuǎn)等配置(其它例如分辨率調(diào)整、權(quán)限變更、系統(tǒng)字體樣式、語(yǔ)言變更等)更改后繼續(xù)留存。

代碼如下:

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: ");
        //創(chuàng)建一個(gè)ViewModel對(duì)象
        mMyViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class);
        textView=findViewById(R.id.textView);
        //ViewModel會(huì)保存數(shù)據(jù),當(dāng)你重新創(chuàng)建的時(shí)候會(huì)加載顯示出來
        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可以看作全局變量倉(cāng)庫(kù)
public class MyViewModel extends ViewModel {
    public int number=0;
}

這樣當(dāng)你旋轉(zhuǎn)屏幕生命周期發(fā)生變化,你的數(shù)據(jù)還在。

到此這篇關(guān)于Android Activity被回收的情況分析的文章就介紹到這了,更多相關(guān)Android Activity被回收內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論