您好,登錄后才能下訂單哦!
一、常見的狀態保存恢復方式
①onSaveInstance + onRestoreInstance
這種方式是最通用的實現狀態保存與恢復,在Android生態種,組件和View大量使用了此方式。
②android:configChanges+onConfigurationChanged
這種情況適用于屏幕旋轉和配置變化,只要作用是阻止Activity重建,因此對于【語言】【時區】的調整可能需要重新啟動Activity才能更新。
注意:
語言的變化需要配置為
android:configChanges="locale|layoutDirection"
屏幕旋轉需要配置為
android:configChanges="orientation|keyboard|screenSize"
③onRetainNonConfigurationInstance
此方法是3.0版本的Android系統中提供了代替方式②的一種方式,使用場景是允許屏幕旋轉、時區和語言調整及時反應。但是對于當前系統的狀態或者進行的任務需要進行保存。
如線程任務
public class NetWorkTask extends Thread { private volatile ProgressUpdateLinster progressUpdateLinster; private Handler handler = new Handler(Looper.getMainLooper()); public NetWorkTask(ProgressUpdateLinster progressUpdateLinster) { this.progressUpdateLinster = progressUpdateLinster; } private int progress = 0; @Override public void run() { while (progress <= 100) { if(progressUpdateLinster != null) { handler.post(new Runnable() { @Override public void run() { progressUpdateLinster.updateProgress(progress); } }); } try { Thread.sleep(200); } catch (InterruptedException e) { return; } progress += 2; } } public interface ProgressUpdateLinster { void updateProgress(int progress); } public void cacel() { interrupt(); } public void setProgressUpdateLinster(ProgressUpdateLinster progressUpdateLinster) { this.progressUpdateLinster = progressUpdateLinster; } }
在Activity中保存狀態
private ProgressBar progressBar; private TextView textView; private static final String TAG = "MainActivity"; NetWorkTask netWorkTask = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progressBar = (ProgressBar) findViewById(R.id.progressbar); textView = (TextView) findViewById(R.id.tv_progroess); if(getLastCustomNonConfigurationInstance() != null && getLastCustomNonConfigurationInstance() instanceof NetWorkTask) { this.netWorkTask = (NetWorkTask) getLastCustomNonConfigurationInstance(); //獲取保存的任務 this.netWorkTask.setProgressUpdateLinster(linster); }else { this.netWorkTask = new NetWorkTask(); netWorkTask.setProgressUpdateLinster(linster); netWorkTask.start(); } } private NetWorkTask.ProgressUpdateLinster linster = new NetWorkTask.ProgressUpdateLinster() { @Override public void updateProgress(int progress) { progressBar.setProgress(progress); textView.setText(progress+"%"); Log.d(TAG,MainActivity.this.toString()); } }; /** * 保存任務 */ @Override public Object onRetainCustomNonConfigurationInstance() { return netWorkTask; }
④RetainFragment
所謂RetainFragment并不是多么高大上的Fragment,和DialogFragment一樣本身都是比較普通的,這里的RetainFragment更注重【用途】,而非Fragment的名稱。
Fragment同樣是Android 3.0 版本的API,不過support-v4中也提供了補充方式。這種保存狀態的原理是將Fragment加入FragmentManager的事務中,但是并不顯示到界面中(也不需要實現view),因此可以成為后臺Fragment。
要實現后臺Fragment,必須做到在Activity重建的時候不被銷毀,原理就是通過setRetainInstance方法實現。
public class WorkFragment extends Fragment { NetWorkTask netWorkTask = null; /** * 重建之后這里的Context會自動替換成新的Activity * @param context */ @Override public void onAttach(Context context) { super.onAttach(context); //第一次啟動的時候,這里network還沒有初始化 //Activity重建之后,更新回調 if(netWorkTask != null) { netWorkTask.setProgressUpdateLinster((NetWorkTask.ProgressUpdateLinster) context); } } @Override public void onDetach() { super.onDetach(); netWorkTask.setProgressUpdateLinster(null); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //重建之后不再會調用此方法 //設置為retain instance Fragment setRetainInstance(true); netWorkTask = new NetWorkTask(); netWorkTask.setProgressUpdateLinster((NetWorkTask.ProgressUpdateLinster) getActivity()); netWorkTask.start(); } }
Activity中的使用方式
public class MainActivity extends AppCompatActivity implements NetWorkTask.ProgressUpdateLinster { private ProgressBar progressBar; private TextView textView; private static final String TAG = "MainActivity"; private static final String TAG_TASK_FRAGMENT = "work"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progressBar = (ProgressBar) findViewById(R.id.progressbar); textView = (TextView) findViewById(R.id.tv_progroess); //如果已經有了work fragment,那就不需要再新建了 if(getSupportFragmentManager().findFragmentByTag(TAG_TASK_FRAGMENT) == null) { getSupportFragmentManager().beginTransaction().add(new WorkFragment(),TAG_TASK_FRAGMENT).commit(); } } @Override public void updateProgress(int progress) { progressBar.setProgress(progress); textView.setText(progress+"%"); } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。