学习总结.
1.创建活动
包 -> New -> Activity -> Empyt Activity, 弹出创建向导, 如下图所示:
编辑 Activity Name(活动名称, 此处我编辑为ShowActivity),
勾选 Generate Layout File , 表示自动为ShowActivity创建一个对应的布局文件
编辑 Layout Name(布局名称, 此处就为activity_show)
勾选 Launcher Activity, 表示将该活动作为当前项目的主活动
勾选 Backwards Compatibility (AppCompat), 表示会为项目启用向下兼容的模式.
点击Finish, 完成活动的创建. ShowActivity代码如下:
public class ShowActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show);
}
}
.在创建好的活动中, 调用了父类的onCreate()方法, 使用setContentView()加载布局.
2. 注册活动
双击编辑AndroidManifest.xml
因为之前的ShowActivity是通过向导来创建活动, Android Studio已在该文件中注册:
如果之前的创建向导中勾选了 Launcher Activity, 注册代码如下所示:
<activity android:name=".activity.ShowActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
如果是通过 包 -> New -> Class 继承 AppCompatActivity 来创建活动, 就需要在此处自行敲入代码了.
额外强调下,注册代码中的 <activity android:name=".ShowActivity">, android: name 属性, 表示活动的位置. 这个位置和manifest层的package属性相关. 比如之前chaungjian的ShowActivit如下图所示:
3. 活动的销毁
在活动中调用 finish(), 销毁当前活动.
4. Intent的使用
Intent可以理解成一个"想要执行的动作", 通畅用于启动活动, 启动服务, 发送广播等.
显式Intent:
Intent的动作非常明显, 称之为"显式Intent"
新建一个动作intent, 在MainActivity活动的基础上, 动作ShowActivity活动.
调用startActivity()执行这个动作.
Intent intent= new Intent(MainActivity.this, ShowActivity.class);
startActivity(intent);
隐式Intent:
不明确支出想要启动哪一个活动,而是指定一系列更加抽象的action和category等信息,交由系统去分析这个intent,并找出合适的活动去启动.
编辑AndroidManifest.xml, 修改ShowActivity的注册信息, 如下所示
<activity android:name=".activity.ShowActivity">
<intent-filter>
<action android:name="com.intent.action.toshow" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
采用隐式启动活动, 代码如下:
Intent intent= new Intent("com.intent.action.toshow");
startActivity(intent);
5. 活动之间的数据传递
活动A 传递 活动B
活动A代码如下:
String data= "data data data";
Intent intent= new Intent(MainActivity.this, ShowActivity.class);
intent.putExtra("data", data);
startActivity(intent);
活动B代码如下:
Intent intent= getIntent();
String data= intent.getStringExtra("data");
Log.d("ShowActivity", data);
活动B 返回 活动A
活动A代码如下:
使用 startActivityForResult() , 第一个参数是Intent, 第二个参数是请求码, 用于在之后的回调中判断数据的来源.
Intent intent= new Intent(MainActivity.this, ShowActivity.class);
startActivityForResult(intent, 1);
活动B代码如下:
使用 setResult() 方法, 是专门用于向上一个活动返回数据. 第一参数参数用于向上一个活动返回处理结果,一般只使用RESULT_OK或RESULT_CANCELED; 第二个参数是把带有数据的Intent传递回去, 然后销毁当前活动.
代码参考如下:
Intent intent= new Intent();
intent.putExtra("data", "data data data ShowActivity");
setResult(RESULT_OK, intent);
finish();
注意: 如果是通过手机Back键返回MainActivity, 在ShowActivity中, 需要重写onBackPressed() 方法来解决(进入ShowActivity, Ctrl+ O, 选择该方法):
@Override
public void onBackPressed() {
Intent intent= new Intent();
intent.putExtra("data", "data data data ShowActivity");
setResult(RESULT_OK, intent);
finish();
}
由于使用 startActivityForResult() 方法启动ShowActivity的, 在ShowActivity被销毁之后, 会回调上一个活动的 onActivityResult() 方法, 因此需要在MainActivity中, 重写这个方法(进入MainActivity, Ctrl+ O, 选择该方法):
onActivityResult() 方法包含三个参数, 第一个参数为启动活动时传入的请求码, 第二个参数为返回数据时传入的处理结果, 第三个参数为带有返回数据的Intent.
代码参考如下:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
switch (requestCode) {
case 1:
if (resultCode== RESULT_OK) {
String rec= data.getStringExtra("data");
Log.d("MainActivity", rec);
}
break;
default:
}
}
6. 活动的状态
Android中的活动是可以叠加的. 每启动一个新的活动, 就会覆盖在原活动之上, 然后点击Back键会销毁最上面的活动, 下面的一个活动就会重新显式出来. Android通过任务(Task)来管理活动, 一个任务就是一组存放在栈里的活动的集合, 这个栈也称为返回栈.
栈是一种后进先出的数据结构, 每启动一个新的活动, 它会在返回栈中入栈, 并处于栈顶的位置, 每当按下Back键或调用finish() 方法销毁活动时, 处于栈顶的活动就会出栈, 这时前一个入栈的活动就会重新处于栈顶的位置. 系统总是会显式处于栈顶的活动给用户.
活动状态分为运行状态, 暂停状态, 停止状态, 销毁状态.
运行状态: 当一个活动位于返回栈的栈顶时, 则处于这个状态.
暂停状态: 当一个活动不再处于栈顶, 但依然可见, 则处于这个状态.
停止状态: 当一个活动不再处于栈顶, 且完全不可见的时候, 则处于这个状态.
销毁状态: 当一个活动从返回栈中移除后, 则处于这个状态.
7. 活动的生命周期:
onCreate() 活动第一次被创建时调用, 完成活动的初始化操作, 比如加载布局, 绑定事件.
onStart() 当活动由不可见变为可见的时候调用.
onResume() 当活动准备好和用户进行交互的时候调用, 此活动一定处于运行状态.
onPause() 当启动或恢复另一个活动的时候调用.
onStop() 当活动完全不可见的时候调用.
onDestroy() 当活动被销毁之前调用.
onRestart() 当活动由停止状态变为运行状态之前调用.
Android官方提供了一张生命周期的示意图, 如下图所示:
8. 活动被回收处理
当活动A启动活动B, 活动A处于停止状态. 如果此时活动A有些数据是用户录入的, 且此时系统内存不足, 将活动A给回收了, 活动B返回活动A会进行重建(onCreate()), 那么活动A之前录入的数据就丢了.
Activity提供了 onSaveInstanceState() 回调方法, 这个方法可以保证在活动被回收之前一定会被调用 可以通过这个方法来解决活动被回收时临时数据得不到保存的问题.
在活动A当中, 重写onSaveInstanceState() 方法, 参考代码如下:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
String name= "test test";
outState.putString("data", name);
}
修改活动A的onCreate() 方法, 添加下方蓝色代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show);
if (savedInstanceState!= null) {
String name= savedInstanceState.getString("data");
Log.d(TAG, name);
}
}
活动A被回收后, 调用了onSaveIntsanceSate() 方法临时保存了数据, 由活动B返回活动A, 活动A进行重建(onCreate()), 再取出临时保存的数据.
9. 活动的启动模式:
standard: 活动默认的启动模式. 使用该模式, 每当启动都会创建该活动的一个新的实例.(一个活动能允许多次创建)
singleTop: 当活动启动时, 如果发现返回栈的栈顶已经是该活动, 则认为可以直接使用它, 不再创建新的活动实例, 反之, 还是会创建新的活动实例.
singleTask: 当活动启动时, 系统首先会在返回栈中检查是否存在该活动的实例, 如果发现已经存在则直接使用该实例, 并把这个活动之上的所有活动全部出栈, 如果没有发现则直接创建一个新的活动实例.
singleInstance: 暂不考虑.
10. 活动的最佳实现:
目前遇到过三种类似的实现方式, 地址在: https://mp.csdn.net/postedit/90692614
11. 启动活动的最佳写法
当活动A 启动 活动B时, 不清楚活动B需要什么参数值, 可以在活动B中提供一个动态方法, 由活动A来调用启动活动B. 该方法需要写清具体所需参数值:
在ShowActivity中加入如下代码:
public static void actionStart(Context context, String name) {
Intent intent= new Intent(context, ShowActivity.class);
intent.putExtra("name", name);
context.startActivity(intent);
}
MainActivity启动ShowActivity时, 可以如下写:
ShowActivity.actionStart(MainActivity.this, "my name is test");
2019-07-24 学习中, 特此记录!