1.Activity的概述
Activity是一个应用组件,用以提供屏幕的交互界面。一个App通常包含多个Activity,其中一个特殊的Activity被指定为main Activity,当用户首次启动该App时,main Activity被首先呈现。一个Activity A可以启动新的Activity B,Activity A将被压入返回栈中,当用户按下后退键退出Activity B后,Activity A将重新获得焦点。
2.Activity的创建
创建一个Activity应该继承Activity或者是其子类(比如ListActivity),然后实现相应的回调方法,下面只列举2个较常见的需实现方法。
(1).onCreate()
实现该方法,初始化一些必须的组件,通过调用setContentView()加载定义好的UI布局xml文件,使用findViewById(int)得到相应布局,可以完成事件的监听初始化!等等操作
(2).onPause()
当一个Activity失去焦点时,该方法将被调用,但该Activity还没被销毁,这个方法应该保存用户的持久数据,比如将用户的数据保存至数据库 xml文件或者其它文件中。
3.Activity的启动
(1).startActivity(intent)
//1.start a new activity Intent intent = new Intent(); intent.setClass(this, NextActivity.class); startActivity(intent);
(2).startActivityForResult(intent, REQUEST_CODE)
private final static int REQUEST_CODE = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* * 2.start a new activity by REQUEST_CODE and can get a resultCode/data * to execute onActivityResult() method */ Intent intent = new Intent(); intent.setClass(this, NextActivity.class); startActivityForResult(intent, REQUEST_CODE); finishActivity(REQUEST_CODE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_CODE: /* * in NextActivity.java, setResult(Activity.RESULT_OK); * and finish(); */ if(resultCode == Activity.RESULT_OK){ //do something } break; default: break; } }
4.Activity的关闭
(1).finish()
通过调用Activity自身的finish()方法,来关闭当前的Activity对象
Activity.this.finish();
(2).finishActivity()
Activity A通过startActivityForResult(intent, REQUEST_CODE)启动新的Activity B,在Activity B中可以结束Activity A对象
ActivityB.this.finishActivity(REQUEST_CODE);
但是在许多情况下,并不使用这些显示的finish方法去结束一个activity,通常android系统去管理,不需要手动结束。如手动结束,将可能很影响用户体验,应尽量少调用!
5.管理Activity的生命周期
管理好activities的生命周期对于开发一个健壮灵活的app至关重要,首先介绍三个重要的状态
(1).其中三种重要状态
1).Resumed
activity处于最前端并且能够得到用户的焦点,可看着running状态
2).Paused
activity启动了一个dialog,先前的activity可见但是失去焦点,此时activity处于Paused状态,该activity依然停留在内存中和依附在窗体管理器上,在系统可用内存极其低的时候才会杀死当前状态的activity。
3).Stopped
activity A启动了一个新的activity B,activity A完全不可见,但是依然停留在内存中,不依附在窗体管理器上,当系统需要内存时,将会杀死该activity,被杀死的概率比Paused状态下的高!
(2).生命周期路线图
Activity完整生命周期路线图
1).entire lifetime
该周期下的activity从onCreate()被调用完成布局xml文件加载 到 onDestroy()释放所有资源.
2).visible lifetime
该周期下的activity从onStart()到onStop(),经历了Activity的可见到完全不可见的过程。可以在onStart()中注册一个BroadcastReceiver,并在onStop()解除这个BroadcastReceiver.
3).foreground lifetime
该周期下的activity从onResume()到onPause(),当前的activity可见但是失去了焦点,比如弹出的一个AlertDialog.
(3).生命周期回调函数概述
注意:在实现某个生命周期回调方法时,应该调用父类的实现方法。
方法 描述 可否杀死 下个方法 onCreate() Activity第一次被创建的时候,调用该方法。比如加载布局文件 设置监听器等等,该方法接收一个Bundle对象,后面将谈到该bundle对象为Activity数据状态的保存所起作用。
no onStart() onRestart() 当activity已经停止即处于Stopped状态后,重新调用onStart()之前会执行该方法 no onStart() onStart() 在activity可见之前,调用该方法 no onResume()
or
onStop()
onResume() 在activity能与用户交互之前,调用该方法。该activity将位于栈顶并获得焦点 no onPause() onPause() 当将要启动一个新的activity时,调用该方法。该方法主要用于提交用户未保存的数据为持久的,停止动画。该方法将执行很快,因为下一个activity不能为resumed状态,直到该activity的onPause()返回 yes onResume()
or
onStop()
onStop() 当activity将处于不可见状态时,调用该方法。有可能因为销毁当前activity或者打开了一个新的activity yes onRestart()
or
onDestroy()
onDestroy() 当activity被销毁之前(可能调用了finish())或者Android系统临时销毁对象节约内存时,执行该方法。 yes nothing (4).Activity在启动模式下的生命周期
6.保存Activity的状态
当一个activity不在栈顶时,系统默认保存activity的状态信息,但我们应该主动地在onPause()方法中保存为持久的状态信息,因为用户可能会退出应用。处在paused和stopped状态下的activity对象依然保存在内存中,然而Android系统在内存不足时将能够杀死这些activity,以释放内存。
当在一个Activity A上,启动一个新的Activity B后,此时Activity A被压入该任务的返回堆中,如果此时系统出现内存不足的情况,它将销毁Activity A,在对象完全销毁之前调用了该activity的onSaveInstanceState()方法,该方法通过bundle对象保存了与当前销毁的Activity有关的信息,用于保存一些与当前activity有关的信息,比如记录控件的信息CheckBox的选择状态(只要控件在xml文件布局中指定唯一的id,bundle就能记录下状态信息,但是如果指定了id且设置android:saveEnabled="false",bundle将不能记录该控件的状态)。当用户按下Back按钮后,由于在返回堆中依然保存Activity A信息,但是此时该对象并不存在,因此需要重新创建该Activity的实例化对象,将系统在销毁A时生成的bundle传入onCreate()中,从而Activity A的状态恢复到销毁前的。
//假设用户旋转了手机屏幕,此时Activity被销毁,在onCreate方法中打印bundle为一下信息 onCreate:: [{android:viewHierarchyState= Bundle[{android:Panels=android.util.SparseArray@40cff310, android:views=android.util.SparseArray@40cff218, android:ActionBar=android.util.SparseArray@40cff5a8}]}]
注意:并不是每个onSaveInstanceState()方法都能够得到执行,如果一个用户在退出activity后,系统能判断该返回堆中,已经到堆底,意味着该应用已经退出,故保存activity的状态已经没有任何意义,故onSaveInstanceState()方法得不到执行!onSaveInstanceState()可能在onPause()之前执行,但是肯定在onStop()之前执行!保存永久性的数据,应该在onPause()中操作,可以将数据保存至数据库或者xml等等!
如果存在一个Activity A,该对象中含有一个EditText控件,在该控件中键入一些字符,然后启动了新的Activity B,一段时间后在Activity B通过back按钮返回至Activity A中,假设此时A对象并没有被销毁,EditText控件中的字符依然存在,在onSaveInstanceState()中并保存bundle状态,当activity压入返回栈后,又重新弹至栈顶时恢复原来的状态!
/* * activity对象处于stopped前,执行onSaveInstanceState()方法,保存相关控件的状态信息, * 比如输入字符,checkbox的选择状态等等 */ onSaveInstanceState:: Bundle[{android:fragments=android.app.FragmentManagerState@40cf3bb0, android:viewHierarchyState=Bundle[{android:Panels=android.util.SparseArray@40cd4df0, android:views=android.util.SparseArray@40cd4cf8, android:ActionBar=android.util.SparseArray@40cf03a8}]}
7.runOnUiThread()
public final void runOnUiThread(Runnable action) { if (Thread.currentThread() != mUiThread) { mHandler.post(action); } else { action.run(); } }
主要用于弹出吐司
public void click(View view){ final Runnable action = new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "ok~~", 0).show(); } }; new Thread(){ public void run() { // 1.工作线程 runOnUiThread(action);//由于该方法的执行实在工作线程中 } }.start(); // 2.工作线程 runOnUiThread(action);//该方法在主线程中执行,可以弹出吐司 }