赞
踩
创建一个activity至少需要三个文件:
这三个文件关联密切,需要理解每个文件是干啥的。推荐大家使用Android Studio自带的新建Activity向导功能。
在工具栏中右键点击包名选择New–>Activity–>Empty Activity菜单项启动新建activty向导。
会弹出下面界面,在这个界面中写好你新建Activity的名字。
新建好之后,Android Studio会给你默认新建这三个文件**:mainfests中注册activity标签、新建Java类、创建该Activity的布局文件**
内存中有没有activity的实例,用户是否可以看到,是否活跃到前台(等待或者接受用户输入中),可以参看下面的各种状态。
用户可以与当前运行状态下的activity交互。设备上有很多应用,但是,任何时候只能有一个activity处于用户能交互的运行状态。
在生命周期图中可以看到,Activity的子类在activity的生命周期状态发生关键性转换时完成某些工作。这些方法通常被称为生命周期回调方法。
如**onCreate(Bundle)**方法。在创建activity实例后,在此实例出现在屏幕上之前,Android操作系统会调用该方法。通常会覆盖onCreate(Bundle)方法,activity可以预处理一下UI相关工作:
切记,千万不要自己去调用onCreate(Bundle)方法或任何其他activity生命周期方法。为通知activty状态变化,你只需在Activity子类里覆盖这些方法,Android会适时调用他们(看当前用户状态以及系统运行情况)。
重写Activty()生命周期方法,并打上日志来进行输出
public class CheatActivity extends AppCompatActivity { private static final String TAG = "CheatActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "onCreate(Bundle) 被调用了"); setContentView(R.layout.activity_cheat); } @Override protected void onStart() { super.onStart(); Log.d(TAG, "onStart(Bundle) 被调用了"); } @Override protected void onStop() { super.onStop(); Log.d(TAG, "onStop(Bundle) 被调用了"); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy(Bundle) 被调用了"); } @Override protected void onPause() { super.onPause(); Log.d(TAG, "onPause(Bundle) 被调用了"); } @Override protected void onResume() { super.onResume(); Log.d(TAG, "onResume(Bundle) 被调用了"); } }
输出如下:
打开Activity()
当打开该Activity时,调用顺序为:onCreate-()–>onStart()–>onResume()
点击主屏幕返回时
调用顺序为:onPause(Bundle),onStop(Bundle) 被调用了;可以看到onDestroy()方法没有被调用,说明,返回主屏幕时,Activity()并没有被摧毁,而是被暂停了,当再次打开时,则回复暂停状态
回退Activity()
然后进行回退时,依次调用onPause(), onStop(),onDestroy();表明,点击回退时说明该Activity没用了,可以进行摧毁
当设备旋转时,看看Activity()的生命周期方法是如何执行的?
设备进行旋转时,系统会销毁当前Activity(),然后创建一个新的Activity()实例。再次旋转设备,又一次见证这个销毁与再创建的过程。
所以你看到日常用到的软件,旋转属性直接被禁止了ovo3
这就出问题了。每次旋转设备,当前的Activity()实例会完全销毁,实例中的存储的一些值就会从内存里被抹掉。旋转后,Android重新创建了Activity的新实例,存储的值被重新初始化。
如何解决设备旋转数据丢失的问题,两种方法
方法一:直接固定方向,不让他旋转(简单暴力)
方法二:通过保存数据来解决
若设备旋转,需要想个办法保存以前的数据。覆盖Activity的一个方法
protected void omSaveInstanceState(Bundle outState)
该方法通常在onStop()方法之前由系统调用,除非用户按后退键。(按后退建就是告诉Android, activity用完了,该activity就完全从内存中被抹掉,自然,也就没必要重建保存数据了。)
方法**onsaveIntsanceState(Bundle)**的默认实现要求所有activity视图将自身状态数据保存在Bundle对象中。Bundle是存储字符串键与限定类型值之间映射关系(键值对)的一种结构。
如下:
@Override
public void onCreate(Bundle saveInstanceState){
super.onCreate(saveInstanceState);
...
}
覆盖onCreate(Bundle)方法时,我们实际是在调用activity超类的onCreate(Bundle)方法,并传入收到的bunle。在超类代码实现里,通过取出保存的视图状态数据,activity的视图层级结构得以重建。
启动另一个activity最简单的方式是使用StartActivity()方法:
public void startAcvtvity(Intent intent)
sartActivity(Intent intent )并不是一个简单的静态方法,activity调用satrtActivity(Intent intent)方法时,调用请求实际发给了操作系统。
准确的说,调用请求发送给了操作系统的ActivityManager,就是那个Activity超级管理员。然后管理员负责创建Activity实例并调用其onCreate(Bundle)方法,如下图所示:
基于intent的通信
intent对象是component用来与操作系统通信的一种媒介工具。常用的组件(component)包括:service、broadcast receiver 以及content provider。
intent 是一种多用途的通信工具。Intent类有多个构造方法,却满足不同的使用需求。
intent用来告诉我ActivityManager该启动哪个activty,因此可使用以下构造方法:
public Intent(Context packageContext, Class<?> cls)
传入该方法的Class类型参数告诉ActivityManager应该启动哪个activity;Context参数告 诉ActivityManager在哪里可以找到它
比如我想启动CheatActivity
public void btn1(View view) {
//新建一个activity并开启
btn_activity_life.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this,CheatActivity.class));
}
});
}
比如现在有俩个activity:MainActivity与CheatActivity,想要让这两个Activity之间进行数据传递,毕竟如果数据没法传递,那真的是没啥意思。
父activity给子发信息
这个比较简单,直接在inetnt中塞需要发送的信息就好了,比如下面这个,点击按钮之后,发生一个键值对
public void btn1(View view) {
//新建一个activity并开启
btn_activity_life.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, CheatActivity.class);
intent.putExtra("username", "suian");
startActivity(intent);
}
});
}
子activity直接从intent中获取信息就可以了
String username = getIntent().getStringExtra("username");
Log.d(TAG, "username: " + username);
从子activity中获取信息
比如,父activity给子activity发送消息后,需要子activity给一个回执信息,具体实现如下:
先把父activity改造一下
private static final int REQUEST_CODE_CHEAT = 0; //确认码
public void btn1(View view) {
//新建一个activity并开启
btn_activity_life.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, CheatActivity.class);
intent.putExtra("username", "suian");
startActivityForResult(intent,REQUEST_CODE_CHEAT);
}
});
}
给子activity发消息时带个确认码REQUEST_CODE_CHEAT,收到信息后需要进行确认是否是的。
子activity发送消息如下:
Intent resData = new Intent();
resData.putExtra("password", "123456");
setResult(RESULT_OK, resData);
用户回退到父activity时,ActivityManager调用父activity的以下方法:
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
该方法的参数来自MainActicity的原始请求代码REQUEST_CODE_CHEAT以及传入setResult(int,Intent )方法的结果代码和intent
父activity接受消息如下:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_CODE_CHEAT) {
if (data == null) {
return;
}
String password = data.getStringExtra("password");
Log.d("CheatActivity", "MainActivity接收到:" + password);
}
}
日志打印如下:当进行回退时,父Activity成功接受到子Activity的信息:password:123456
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。