您的位置:首页 > 移动开发 > Android开发

Android学习随笔(3)------活动的生命周期

2017-10-11 10:42 232 查看
学习流程来自《第一行代码》(第二版)

活动的生命周期

熟悉了一下活动之间的切换了之后,就需要深入的了解一下活动的生命周期。

Android的Activity是放在返回栈中的。

先来看一下来自官网的图



活动的状态总共有4种。

运行状态:位于返回栈栈顶,用户正在使用的。

暂停状态:不位于返回栈栈顶,但是还是被用户可见的Activity。

停止状态:不位于返回栈栈顶,且不可见,但系统仍会为其保留数据,知道其他地方内存不够时,数据才会被系统会回收。

销毁状态:活动从返回栈移除。

onCreate(): 在活动第一次被创建的时候被调用,各种初始化。

onStart(): 活动由不可见变为可见时被调用,资源加载。

onResume(): 活动准备好和用户进行交互的时候调用。活动位于返回栈栈顶,且处于运行状态。

onPause(): 系统准备去启动或者恢复另一个活动的时候调用。(启动一个对话框式的Activity调用此方法)

onStop(): 在活动完全不可见时调用,资源释放。

onDestroy(): 在活动被销毁之前调用,释放内存。

onRestart(): 在活动由停止状态变为运行状态之前调用,活动被重新启动。

活动的三种生存期:

完整生存期: onCreate()—onDestroy()

可见生存期: onStart()—onStop()

前台生存期 :onResume()—onPause()

新建一个Project

分别创建两个子活动NormalActivity和DialogActivity

normal_layout.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="This is a normal activity"
/>
</LinearLayout>


在这个界面显示一段文字”This is normal activity”

dialog_layout.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="This is a dialog activity"
/>

</LinearLayout>


这个页面我们也显示一段文字,但是我们给这个Activity取名为dialog,这说明他是一个对话框。

在AndroidManifest.xml中完成对它的设置

<activity android:name=".Dialog_Activity"
android:theme="@style/Theme.AppCompat.Dialog"></activity><!--给当前活动指定主题 @android:style/Theme.Dialog     @style/Theme.AppCompat.Dialog  (兼容主题)-->


书上的代码是android:theme=”@android:style/Theme.Dialog”,但是报错。找了一下网上感觉比较正确的解释是android:theme=”@android:style/Theme.Dialog”需要public class Dialog_Activity extends Activity。

而@style/Theme.AppCompat.Dialog即是AndroidStudio在创建Activity默认继承

AppCompatActivity时使用的。(public class Dialog_Activity extends AppCompatActivity {)

所以根据书上进行代码实现的时候记得使Dialog_Activity继承自Activity。

在activity_main.xml中

添加两个按钮分别用于打开上面新建的两个Activity。

<?xml version="1.0" encoding="utf-8"?>
<!--</android.support.constraint.ConstraintLayout>-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
android:id="@+id/start_normal_activity"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Start NormalActivity"
/>
<Button
android:id="@+id/start_dialog_activity"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Start DialogActivity"
/>
</LinearLayout>




最后在MainAcitivty.java中完成对另外两个Activity的Intent,以及对于一开始那7个方法的一个日志输出。

public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG,"onCreate");
Button startNormalActivity = (Button)findViewById(R.id.start_normal_activity);
final Button startDialogActivity = (Button)findViewById(R.id.start_dialog_activity);
startNormalActivity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intentnormal = new Intent(MainActivity.this,Normal_Activity.class);
startActivity(intentnormal);
}
});
startDialogActivity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intentdialog = new Intent(MainActivity.this,Dialog_Activity.class);
startActivity(intentdialog);
}
});

}

@Override
protected void onStart() {
super.onStart();
Log.d(TAG,"onStart");
}

@Override
protected void onResume() {
super.onResume();
Log.d(TAG,"onResume");
}

@Override
protected void onPause() {
super.onPause();
Log.d(TAG,"onPause");
}

@Override
protected void onStop() {
super.onStop();
Log.d(TAG,"onStop");
}

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

@Override
protected void onRestart() {
super.onRestart();
Log.d(TAG,"onRestart");
}
}


点击运行按钮



可以看到第一次被创建时依次执行onCreate(),onStart(),onResume()。

点击start_normal_activity可以看到



由于NormalActivity把MainActivity完全挡住了,依次被调用的是onPause(),onStop()。

接下来back键返回MainActivity



由于MainActivity已经进入了停止状态,所以onRestart()方法会得到执行,之后会依次执行onStart(),onResume()这两个方法。

点击start_dialog_activity



可以看到Dialog并没有完全挡住MainActivity,此时MainActivity只是进入了暂停状态斌没有进入停止状态,onPause()被调用。

回到MainActivity



onResume()被调用。

再次按下back键



onPause(),onStop(),onDestroy()依次被调用,最终销毁MainActivity。

当活动进入停止状态,且系统内存不够用的时候,这个活动是有可能被回收的。但回收了的话,之前在Activity上的数据不也就一起被系统回收了嘛,这时候Bundle就派上用场了。

在MainActivity.java中添加

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
String tempData = "Something you just typed";
outState.putString("data_key",tempData);
}


修改onCreater()方法

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState != null) {
String tempData = savedInstanceState.getString("data_key");
Log.d(TAG,tempData);
}    // 当内存不足此页被回收掉时,打开会重新调用onCreate方法,之前页面上经过bundle保存的内容将重新被填写
Log.d(TAG,"onCreate");
Button startNormalActivity = (Button)findViewById(R.id.start_normal_activity);
final Button startDialogActivity = (Button)findViewById(R.id.start_dialog_activity);
startNormalActivity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intentnormal = new Intent(MainActivity.this,Normal_Activity.class);
startActivity(intentnormal);
}
});
startDialogActivity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intentdialog = new Intent(MainActivity.this,Dialog_Activity.class);
startActivity(intentdialog);
}
});
}


关于Intent传值还有许多的方法,作者在书中留下了一个思路。

Intent利用Bundle传值

若每一次传值都用Intent是十分麻烦的,比如有三个页面1 2 3,现在要把值通过1经过2传给3,如果我们用Intent的话,1传到2先写一遍,再在B中都取出来,然后再把值put到Intent中,再切换到3,这是一件十分麻烦的事情。

但如果在1中用了Bundle传值,只需要把Bundle传给B,再在B中传给C, C就可以得到你想要传递的值了。

用一个小例子来体会一下Bundle传值,创建两个Activity,MainActivity上放一个button,FirstActivity上的button点击跳转到SecondActivity。

FirstActivity.java:

Log.d("FirstActivity","This is FirstActivity");
if (savedInstanceState != null) {
Log.d("FirstActivity",savedInstanceState.getString("SecondActivity"));
}
Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putString("FB","This is FirstActivity's bundle");
intent.putExtras(bundle);
startActivity(intent);
}
});


值传入Bundle,再传入Intent,传递给SecondActivity。

SecondActivity.java:

Bundle bundle = this.getIntent().getExtras();
Log.d("SecondActivity",bundle.getString("FB"));


用来显示FirstActivity传递进来的值。



此博文为个人学习笔记,仅供个人学习使用,希望对大家有帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android