Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案
Android屏幕旋转适配全解析

Android屏幕旋转适配全解析这篇博⽂给⼤家介绍下,当⼿机屏幕旋转时我们应当怎么去处理,⾸先了解下默认情况下Android进⾏屏幕旋转的原理,当⼿机进⾏旋转时重⼒感应sensor起到作⽤,会将Activity销毁并按照横屏的屏幕尺⼨进⾏重新构造,⽣命周期如下图所⽰,⼀句话总结就是默认情况下Activity进⾏屏幕旋转会⾃动进⾏onDestroy并重新onCreate。
这⾥写图⽚描述 *onSaveInstanceState和onRestoreInstanceState⽤处后⾯会介绍到。
先介绍2种⾮默认情况下的操作 1:禁⽌屏幕旋转 在AndroidManifest.xml的Activity中配置 始终竖屏?1android:screenOrientation="portrait"始终横屏?1<code class="hljs avrasm">android:screenOrientation="landscape"</code>2:Activity跟随旋转但不销毁和重启这个实现原理是告诉系统这个Activity的旋转处理由我们⾃⼰去处理,不⽤帮我销毁和重启在AndroidManifest.xml的Activity中配置?1<code class="hljs avrasm">android:configChanges="keyboardHidden|orientation|screenSize"</code>然后在Activity中进⾏⽅法复写,监听屏幕旋转并处理?12 3 4 5 6 7 8 9 10 11<code class="hljs java"> @Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { Toast.makeText(MainActivity.this, "竖屏模式", 3000).show();} else{Toast.makeText(MainActivity.this, "横屏模式", 3000).show();}}</code>接下来介绍,Activity进⾏默认旋转时候的处理,当屏幕进⾏旋转的时候会按照横屏的分辨率进⾏重绘,当然你也可以不进⾏任何处理难看就难看呗:),理想状态的处理就是建⽴两套同名的Layout,当屏幕旋转时系统会⾃动帮我们加载横屏的Layout。
如何在 Android 程序中禁止屏幕旋转和重启Activity

如何在Android 程序中禁止屏幕旋转和重启Activity禁止屏幕随手机旋转变化有时候我们希望让一个程序的界面始终保持在一个方向,不随手机方向旋转而变化:在AndroidManifest.xml的每一个需要禁止转向的Activity配置中加入android:screenOrientation=”landscape”属性。
landscape = 横向portrait = 纵向避免在转屏时重启Activityandroid中每次屏幕方向切换时都会重启Activity,所以应该在Activity销毁前保存当前活动的状态,在Activity再次Create的时候载入配置,那样,进行中的游戏就不会自动重启了!要避免在转屏时重启Activity,可以通过在AndroidManifest.xml文件中重新定义方向(给每个Activity加上android:configChanges=”keyboardHidden|orientation”属性)。
在需要控制屏幕显示方向的Activity中重写onConfigurationChanged(Configuration newConfig)方法,这样在转屏时就不会重启Activity了。
if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE) {//横向setContentView(yout.file_list_landscape);} else {//竖向setContentView(yout.file_list);}<activity android:name="com.myapp.MyActivity"android:label="@string/app_name"android:screenOrientation="landscape"android:configChanges="orientation"><intent-filter><action android:name="android.intent.action.VIEW"/><category android:name="android.intent.category.DEFAULT"/></intent-filter></activity>android:screenOrientation=”landscape”android:configChanges=”keyboardHidden|orientation”@Overridepublicvoid onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig);if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE) { //横向setContentView(yout.file_list_landscape);} else {//竖向setContentView(yout.file_list);}}在模拟器中可以按CTL+F11 模拟做屏幕旋转。
Android强制设置屏幕旋转方向Forcerotation

Android强制设置屏幕旋转⽅向Forcerotation 第⼀种⽅法:⾸先检查有没有权限,没有就去申请。
申请时会触发frameworks/base/services/core/java/com/android/server/wm/AlertWindowNotification.java⾥⾯弹出可以覆盖view的权限窗⼝。
检查和处理的code如下:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){if (!Settings.canDrawOverlays(this)){Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,Uri.parse("package:" + getPackageName()));startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);return;}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data){if (requestCode == OVERLAY_PERMISSION_REQ_CODE){if (Settings.canDrawOverlays(this)){//Already has permission}}}实际去锁定旋转和恢复的code如下:public final static int STATE_DEFAULT = 0;public final static int STATE_PORTRAIT = 1;public final static int STATE_LANDSCAPE = 8;WindowManager mWindowManager;View mView;youtParams lp;mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);int iFlags = youtParams.FLAG_LAYOUT_IN_SCREEN |youtParams.FLAG_WATCH_OUTSIDE_TOUCH |youtParams.FLAG_NOT_TOUCH_MODAL |youtParams.FLAG_NOT_FOCUSABLE |youtParams.FLAG_SHOW_WHEN_LOCKED;lp = new youtParams(youtParams.MATCH_PARENT,youtParams.MATCH_PARENT,youtParams.TYPE_SYSTEM_OVERLAY,iFlags,PixelFormat.TRANSLUCENT);mView = new View(this);switch (rotation){//Normal Operationcase MainActivity.STATE_DEFAULT:if (mAdded == true) mWindowManager.removeView(mView);mAdded = false;break;//Force Rotationcase MainActivity.STATE_LANDSCAPE:case MainActivity.STATE_PORTRAIT:lp.screenOrientation = rotation;if (mAdded == false){mWindowManager.addView(mView, lp);mAdded = true;}else{mWindowManager.updateViewLayout(mView, lp);}break;}上⾯的⽅法在添加system权限后,可以直接获得权限,不再需要申请。
Android AsyncTask解析

Android AsyncTask解析我们都知道,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制,参考之前一篇文章Android 异步消息处理机制:Looper、Handler、Message。
但是费时的任务操作总会启动一些匿名的子线程,太多的子线程会给系统带来巨大的负担,随之带来一些性能问题。
因此Android提供了一个工具类AsyncTask,顾名思义异步执行任务,使用它就可以非常灵活方便地从子线程切换到UI线程。
AsyncTask的基本用法由于AsyncTask是一个抽象类,所以如果我们想使用它,就必须要创建一个子类去继承它。
在继承时我们可以为AsyncTask类指定三个泛型参数Params,Progress和Result,这三个参数的用途如下:Params传入doInBackground()方法的参数类型。
启动任务执行的输入参数,比如HTTP请求的URL。
Progress传入onProgressUpdate()方法的参数类型。
后台任务执行的百分比。
Result传入onPostExecute()方法的参数类型,也是doInBackground()方法返回的类型。
后台执行任务最终返回的结果,比如String,Integer等AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,开发者需要实现这些方法:onPreExecute()该方法将在执行实际的后台操作前被UI 线程调用。
可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。
doInBackground(Params…)将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。
这里将主要负责执行那些很耗时的后台处理工作。
可以调用publishProgress方法来更新实时的任务进度。
该方法是抽象方法,子类必须实现。
android实训自我评价

android实训自我评价我的Android实训自我评价在过去的几个月中,我参加了一次Android开发的实训课程。
这个实训课程让我对Android开发有了更深入的了解,并提供了我在实际项目中应用所学知识的机会。
在这篇文章中,我将详细回答关于我在Android实训中的经历和所获得的技能的问题。
1. 我在实训中学到了哪些重要的Android开发技能?在实训中,我学到了很多重要的Android开发技能。
首先,我学会了使用Android Studio这个强大的开发工具。
我学习了如何创建新的项目、配置开发环境、导入依赖库等。
此外,我还学会了使用Gradle来管理项目的依赖关系。
其次,我深入了解了Android应用的基本组件,包括活动(Activity)、碎片(Fragment)、服务(Service)和广播接收器(Broadcast Receiver)。
我学习了如何在这些组件之间进行通信和数据传递。
此外,我还学习了如何处理用户界面(UI)事件和屏幕旋转等方面的问题。
此外,我还学习了如何使用Android框架中提供的各种API。
比如,我学会了使用网络请求库(如Volley)来处理HTTP请求,使用数据库来存储和检索数据(如SQLite),以及使用分享功能和地理位置服务等。
最重要的是,我学会了如何适应不同的Android设备和版本。
我了解了不同设备的屏幕分辨率、像素密度和尺寸差异,以及如何编写适配不同屏幕尺寸的布局文件。
此外,我还学习了如何检测和处理不同的Android版本中的兼容性问题。
2. 我在实训中遇到的最大困难是什么?我是如何克服的?在实训中,我遇到了一些困难。
其中最大的困难之一是布局的设计与适配。
由于Android设备的多样性,在不同的设备上,布局可能会有所不同。
我曾经因为没有考虑到不同设备分辨率的差异,而导致应用在某些设备上的布局错乱。
为了解决这个问题,我学习了如何使用约束布局和百分比布局,以确保应用在不同设备上都能正确地显示。
AndroidUI设计系列之ImageView实现ProgressBar旋转效果(1)

AndroidUI设计系列之ImageView实现ProgressBar旋转效果(1)提起ProgressBar,想必⼤家都⽐较熟悉,使⽤起来也是⽐较⽅便,直接在XML⽂件中引⽤,然后添加属性,运⾏就OK了,虽然使⽤ProgressBar很⽅便但是在我们开发的每⼀个应⽤基本上都有⾃⼰的主体风格,如果使⽤了系统⾃带的效果图,给⼈的感觉是和总体风格太不搭配了,看上去很是别扭,我们⾃⼰开发也觉得不爽,于是就想着⾃定义⼀下效果,其实⾃定义ProgressBar的效果也不难,⼤概可分为三步⾛吧:⼀、在anim⽂件夹下使⽤animation-list定义动画集<?xml version="1.0" encoding="UTF-8"?><animation-list android:oneshot="false" xmlns:android="/apk/res/android"><item android:duration="50" android:drawable="@drawable/circle_10001" /><item android:duration="50" android:drawable="@drawable/circle_10002" /><item android:duration="50" android:drawable="@drawable/circle_10003" /><item android:duration="50" android:drawable="@drawable/circle_10004" /><item android:duration="50" android:drawable="@drawable/circle_10005" /><item android:duration="50" android:drawable="@drawable/circle_10006" /><item android:duration="50" android:drawable="@drawable/circle_10007" /></animation-list>⼆、在style.xml⽂件中定义风格<style name="CircleProgressStyle" parent="@android:style/rge"><item name="android:indeterminateDrawable">@anim/anim_progress_circle</item></style>三、在使⽤ProgressBar的xml⽂件中设置其style<ProgressBarandroid:layout_width="50dip"android:layout_height="50dip"style="@style/CircleProgressStyle"/>通过以上步骤,基本上就可以实现⾃⼰想要的效果了,这也是我在开发中⼀直习惯使⽤的⽅式,当然了使⽤其它⽅式同样可以实现这种效果,今天我主要是想讲⼀下使⽤AnimationDrawable 和ImageView结合来实现上述效果,所以以上⽅法就不再详解了(如果⼤家想了解其它的⽅式,留你邮箱,给你回信)。
android期末考试题及答案
android期末考试题及答案一、选择题(每题2分,共20分)1. Android操作系统是基于哪个内核开发的?A. Linux内核B. Windows内核C. Unix内核D. MacOS内核答案:A2. 在Android开发中,哪个类是所有Activity的基类?A. ContextB. ViewC. ActivityD. Application答案:C3. Android应用程序的UI布局文件通常保存在哪个目录下?A. /res/values/B. /res/drawable/C. /res/layout/D. /assets/答案:C4. 下列哪个不是Android四大组件之一?A. ActivityB. ServiceC. Content ProviderD. Widget答案:D5. Android中,Intent主要用于什么?A. 启动ActivityB. 启动ServiceC. 启动BroadcastReceiverD. 所有以上答案:D6. 在Android中,下列哪个不是布局控件?A. LinearLayoutB. RelativeLayoutC. TextViewD. ImageView答案:C7. Android中,哪个方法用于处理屏幕旋转等配置更改?A. onCreate()B. onStart()C. onConfigurationChanged()D. onDestroy()答案:C8. 在Android开发中,哪个类用于处理网络请求?A. HttpURLConnectionB. HttpUrlConnectionC. NetworkConnectionD. InternetConnection答案:A9. Android的事件传递机制中,哪个方法用于处理触摸事件?A. onTouchEvent()B. onClick()C. onLongClick()D. onTouchEvent()答案:A10. Android中,哪个类用于处理异步任务?A. AsyncTaskB. SyncTaskC. BackgroundTaskD. Thread答案:A二、填空题(每空2分,共20分)1. Android应用程序的入口点是 __________ 类。
解密Android测试中的屏幕旋转和布局适配问题
解密Android测试中的屏幕旋转和布局适配问题在Android开发中,屏幕旋转和布局适配是一个常见而又众多开发者头疼的问题。
当用户旋转设备时,应用程序的布局和界面需要适应新的屏幕尺寸和方向。
这就需要开发者在测试中解密并解决屏幕旋转和布局适配问题。
本文将详细介绍如何处理这些问题,以确保应用程序在不同屏幕旋转和尺寸下的正常运行。
一、了解屏幕旋转和布局适配的概念在开始解决问题之前,让我们先了解一下屏幕旋转和布局适配的概念。
1. 屏幕旋转:屏幕旋转指的是用户将设备从竖屏模式切换到横屏模式或反之。
在旋转过程中,应用程序需要根据新的屏幕尺寸和方向重新布局和适配。
2. 布局适配:布局适配是指根据屏幕的尺寸和方向来调整应用程序的布局,以保证应用程序在不同设备上正常显示,并提供良好的用户体验。
二、解密屏幕旋转问题屏幕旋转时,会触发Android系统重新创建Activity的生命周期。
这就需要开发者进行一些额外的处理,以确保数据的持久性和用户体验的连续性。
1. 保存和恢复数据:在Activity或Fragment中,可以重写onSaveInstanceState方法来保存相关数据。
然后,在onCreate或onRestoreInstanceState方法中恢复这些数据。
这样,即使屏幕旋转,用户也能够看到之前输入的数据。
2. 使用特定布局:为了适应不同的屏幕尺寸和方向,可以为不同的布局创建不同的资源文件。
例如,可以创建一个layout-land文件夹,用于存放横屏模式下的布局文件。
系统会根据设备的方向自动加载相应的布局文件。
三、解密布局适配问题布局适配问题主要包括适配不同屏幕尺寸和适配不同屏幕密度两个方面。
1. 适配不同屏幕尺寸:Android提供了多种方法来适配不同屏幕尺寸,其中一种常见的方法是使用权重(weight)属性来定义布局中各个控件的比例关系。
另外,还可以使用相对布局(RelativeLayout),通过设置各个控件之间的相对位置来适应不同的屏幕尺寸。
如何让Android横竖屏切换时不销毁当前activity
首先在Mainifest.xml的Activity元素中加入android:configChanges="orientation|keyboardHidden"属性<activity android:name=".FileBrowser"android:label="@string/app_name"android:configChanges="orientation|keyboardHidden "><intent-filter><actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="UNCHER"/> </intent-filter></activity>加入这条属性的含义是,应用程序将会处理屏幕方向和键盘状态(推出或合上)信息的改动。
但对于其他的设备配置信息的改动则会由Android系统来处理(销毁当前Activity,然后重启一个新的Activity 实例)。
那么,现在还需要在java代码的activity子类中加入配置信息改动的处理代码。
这个也很简单/*** onConfigurationChanged* the package:android.content.res.Configuration. * @param newConfig, The new device configuration. * 当设备配置信息有改动(比如屏幕方向的改变,实体键盘的推开或合上等)时,* 并且如果此时有activity正在运行,系统会调用这个函数。
* 注意:onConfigurationChanged只会监测应用程序在AnroidMainifest.xml中通过* android:configChanges="xxxx"指定的配置类型的改动; * 而对于其他配置的更改,则系统会onDestroy()当前Activity,然后重启一个新的Activity实例。
Android实现屏幕旋转方法总结
Android实现屏幕旋转⽅法总结本⽂实例总结了Android实现屏幕旋转⽅法。
分享给⼤家供⼤家参考。
具体如下:在介绍之前,我们需要先了解默认情况下android屏幕旋转的机制:默认情况下,当⽤户⼿机的重⼒感应器打开后,旋转屏幕⽅向,会导致当前activity发⽣onDestroy-> onCreate,这样会重新构造当前activity和界⾯布局,如果在Camera界⾯,则表现为卡顿或者⿊屏⼀段时间。
如果是在横竖屏UI设计⽅⾯,那么想很好地⽀持屏幕旋转,则建议在res中建⽴layout-land和layout-port两个⽂件夹,把横屏和竖屏的布局⽂件分别放⼊对应的layout⽂件夹中。
了解了这些以后,我们对android的屏幕旋转⽅法进⾏如下总结:1. AndroidManifest.xml设置如果单单想设置横屏或者竖屏,那么只需要添加横竖屏代码:android:screenOrientation="landscape"横屏设置;android:screenOrientation="portrait"竖屏设置;这种⽅法的优点:即使屏幕旋转,Activity也不会重新onCreate。
缺点:屏幕只有⼀个⽅向。
2. 代码动态设置如果你需要动态改变横竖屏设置,那么,只需要在代码中调⽤setRequestedOrientation()函数:setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//横屏设置setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏设置setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);//默认设置这种⽅法优点:可以随意动态设置,满⾜我们⼈为改变横竖屏的要求,同时满⾜横竖屏UI不同的设计需求;缺点:如果改变设置,那么,Activity会被销毁,重新构建,即重新onCreate;3. 重写onConfigurationChanged如果你不希望旋转屏幕的时候Activity被不断的onCreate(这种情况往往会造成屏幕切换时的卡顿),那么,可以使⽤此⽅法:⾸先,在AndroidMainfest.xml中添加configChanges:<activity android:name=".Test"android:configChanges="orientation|keyboard"></activity>注意,keyboardHidden表⽰键盘辅助功能隐藏,如果你的开发API等级等于或⾼于13,还需要设置screenSize,因为screenSize会在屏幕旋转时改变;android:configChanges="keyboardHidden|orientation|screenSize"然后,在Activity中重写onConfigurationChanged⽅法,这个⽅法将会在屏幕旋转变化时,进⾏监听处理:public void onConfigurationChanged(Configuration newConfig) {// TODO Auto-generated method stubsuper.onConfigurationChanged(newConfig);if (newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE){// Nothing need to be done here} else {// Nothing need to be done here}}这个⽅法的优点:我们可以随时监听屏幕旋转变化,并对应做出相应的操作;缺点:它只能⼀次旋转90度,如果⼀下⼦旋转180度,onConfigurationChanged函数不会被调⽤。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Android 屏幕旋转处理AsyncTask 和ProgressDialog的最佳方案转载请表明出处:/lmj623565791/article/details/37936275 1、概述众所周知,Activity在不明确指定屏幕方向和configChanges 时,当用户旋转屏幕会重新启动。
当然了,应对这种情况,Android给出了几种方案: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。
c)谷歌的官方不建议使用ProgressDialog,这里我们会使用官方推荐的DialogFragment来创建我的加载框,如果你不了解:请看Android 官方推荐: DialogFragment 创建对话框。
这样,其实给我们带来一个很大的问题,DialogFragment说白了是Fragment,和当前的Activity的生命周期会发生绑定,我们旋转屏幕会造成Activity的销毁,当然也会对DialogFragment造成影响。
下面我将使用几个例子,分别使用上面的3种方式,和如何最好的解决上述的问题。
3、使用onSaveInstanceState()和onRestoreInstanceState()进行数据保存与恢复代码:[java] view plaincopypackagecom.example.zhy_handle_runtime_change; import java.util.ArrayList; import java.util.Arrays; import android.app.DialogFragment; importandroid.app.ListActivity; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.widget.ArrayAdapter; importandroid.widget.ListAdapter; /** * 不考虑加载时,进行旋转的情况,有意的避开这种情况,后面例子会介绍解决方案* @author zhy * */ public class SavedInstanceStateUsingActivity extends ListActivity { private static final String TAG = "MainActivity"; private ListAdapter mAdapter; privateArrayList<String> 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<String>( SavedInst anceStateUsingActivity.this,yout.simple_list_item_1, mDatas); setListAdapter(mAdapter); } @Override protected void onRestoreInstanceState(Bundle state) { super.onRestoreInstanceState(state);Log.e(TAG, "onRestoreInstanceState"); }@Override protected voidonSaveInstanceState(Bundle outState){ super.onSaveInstanceState(outState);Log.e(TAG, "onSaveInstanceState");outState.putSerializable("mDatas", mDatas); }/** * 模拟耗时操作* * @return */ private ArrayList<String> generateTimeConsumingDatas() { try { Thread.sleep(2000); } catch (InterruptedException e) { }return new ArrayList<String>(Arrays.asList("通过Fragment保存大量数据","onSaveInstanceState保存数据", "getLastNonConfigurationInstance已经被弃用", "RabbitMQ", "Hadoop","Spark")); } private class LoadDataAsyncTask extends AsyncTask<Void, Void, Void> { @Overrideprotected Void doInBackground(Void... params){ mDatas = generateTimeConsumingDatas(); returnnull; } @Overrideprotected void onPostExecute(Void result){ mLoadingDialog.dismiss();initAdapter(); } } @Override protected void onDestroy() { Log.e(TAG, "onDestroy"); super.onDestroy(); } } 界面为一个ListView,onCreate中启动一个异步任务去加载数据,这里使用Thread.sleep模拟了一个耗时操作;当用户旋转屏幕发生重新启动时,会onSaveInstanceState中进行数据的存储,在onCreate中对数据进行恢复,免去了不必要的再加载一遍。
运行结果:当正常加载数据完成之后,用户不断进行旋转屏幕,log会不断打出:onSaveInstanceState->onDestroy->onCreate->on RestoreInstanceState,验证我们的确是重新启动了,但是我们没有再次去进行数据加载。
如果在加载的时候,进行旋转,则会发生错误,异常退出(退出原因:dialog.dismiss()时发生NullPointException,因为与当前对话框绑定的FragmentManager为null,又有兴趣的可以去Debug,这个不是关键)。
效果图:4、使用Fragment来保存对象,用于恢复数据如果重新启动你的Activity需要恢复大量的数据,重新建立网络连接,或者执行其他的密集型操作,这样因为配置发生变化而完全重新启动可能会是一个慢的用户体验。
并且,使用系统提供的onSaveIntanceState()的回调中,使用Bundle 来完全恢复你Activity的状态是可能是不现实的(Bundle不是设计用来携带大量数据的(例如bitmap),并且Bundle 中的数据必须能够被序列化和反序列化),这样会消耗大量的内存和导致配置变化缓慢。
在这样的情况下,当你的Activity因为配置发生改变而重启,你可以通过保持一个Fragment来缓解重新启动带来的负担。
这个Fragment可以包含你想要保持的有状态的对象的引用。