学习流程来自《第一行代码》(第二版)
活动的生命周期
熟悉了一下活动之间的切换了之后,就需要深入的了解一下活动的生命周期。
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传递进来的值。
此博文为个人学习笔记,仅供个人学习使用,希望对大家有帮助。