设为首页 加入收藏

TOP

Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案(一)
2015-08-31 21:25:00 来源: 作者: 【 】 浏览:77
Tags:Android 屏幕 旋转 处理 AsyncTask ProgressDialog 最佳 方案

a、如果是少量数据,可以通过onSaveInstanceState()和onRestoreInstanceState()进行保存与恢复。


Android会在销毁你的Activity之前调用onSaveInstanceState()方法,于是,你可以在此方法中存储关于应用状态的数据。然后你可以在onCreate()或onRestoreInstanceState()方法中恢复。


b、如果是大量数据,使用Fragment保持需要恢复的对象。


c、自已处理配置变化。


注:getLastNonConfigurationInstance()已经被弃用,被上述方法二替代。


2、难点


假设当前Activity在onCreate中启动一个异步线程去夹在数据,当然为了给用户一个很好的体验,会有一个ProgressDialog,当数据加载完成,ProgressDialog消失,设置数据。


这里,如果在异步数据完成加载之后,旋转屏幕,使用上述a、b两种方法都不会很难,无非是保存数据和恢复数据。


但是,如果正在线程加载的时候,进行旋转,会存在以下问题:


a)此时数据没有完成加载,onCreate重新启动时,会再次启动线程;而上个线程可能还在运行,并且可能会更新已经不存在的控件,造成错误。


b)关闭ProgressDialog的代码在线程的onPostExecutez中,但是上个线程如果已经杀死,无法关闭之前ProgressDialog。


下面我将使用几个例子,分别使用上面的3种方式,和如何最好的解决上述的问题。


本文相关源码下载地址


------------------------------------------分割线------------------------------------------


具体下载目录在 /2015年资料/8月/8日/Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案/


------------------------------------------分割线------------------------------------------


3、使用onSaveInstanceState()和onRestoreInstanceState()进行数据保存与恢复


代码:


package com.example.zhy_handle_runtime_change;


import java.util.ArrayList;
import java.util.Arrays;


import android.app.DialogFragment;
import android.app.ListActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
/**
?* 不考虑加载时,进行旋转的情况,有意的避开这种情况,后面例子会介绍解决方案
?* @author zhy
?*
?*/
public class SavedInstanceStateUsingActivity extends ListActivity
{
?private static final String TAG = "MainActivity";
?private ListAdapter mAdapter;
?private ArrayList mDatas;
?private DialogFragment mLoadingDialog;
?private LoadDataAsyncTask mLoadDataAsyncTask;


?@Override
?public void onCreate(Bundle savedInstanceState)
?{
? super.onCreate(savedInstanceState);
? Log.e(TAG, "onCreate");
? initData(savedInstanceState);
?}


?/**
? * 初始化数据
? */
?private void initData(Bundle savedInstanceState)
?{
? if (savedInstanceState != null)
? ?mDatas = savedInstanceState.getStringArrayList("mDatas");


? if (mDatas == null)
? {
? ?mLoadingDialog = new LoadingDialog();
? ?mLoadingDialog.show(getFragmentManager(), "LoadingDialog");
? ?mLoadDataAsyncTask = new LoadDataAsyncTask();
? ?mLoadDataAsyncTask.execute();
? ?
? } else
? {
? ?initAdapter();
? }


?}


?/**
? * 初始化适配器
? */
?private void initAdapter()
?{
? mAdapter = new ArrayAdapter(
? ? SavedInstanceStateUsingActivity.this,
? ? android.R.layout.simple_list_item_1, mDatas);
? setListAdapter(mAdapter);
?}


?@Override
?protected void onRestoreInstanceState(Bundle state)
?{
? super.onRestoreInstanceState(state);
? Log.e(TAG, "onRestoreInstanceState");
?}


?@Override
?protected void onSaveInstanceState(Bundle outState)
?{
? super.onSaveInstanceState(outState);
? Log.e(TAG, "onSaveInstanceState");
? outState.putSerializable("mDatas", mDatas);


?}


?private class LoadDataAsyncTask extends AsyncTask
?{
? @Override
? protected Void doInBackground(Void... params)
? {
? ?mDatas = generateTimeConsumingDatas();
? ?return null;
? }


? @Override
? protected void onPostExecute(Void result)
? {
? ?mLoadingDialog.dismiss();
? ?initAdapter();
? }
?}


?@Override
?protected void onDestroy()
?{
? Log.e(TAG, "onDestroy");
? super.onDestroy();
?}


}


界面为一个ListView,onCreate中启动一个异步任务去加载数据,这里使用Thread.sleep模拟了一个耗时操作;当用户旋转屏幕发生重新启动时,会onSaveInstanceState中进行数

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Android开发学习之Adapter(数据适.. 下一篇Android 官方推荐:DialogFragment..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: