开门见山,既然要介绍Activity,那我们现在要明白Activity是干什么的?
以上是百度百科概要说明,总结一句话就是:Activity就是负责与用户交互的一个应用组件,显示的页面。
当前Activity正处于运行状态,指的是当前Activity获取了焦点
当前Activity正处于暂停状态,指的是当前Activity失去焦点,此时的Activity并没有被销毁,内存里面的成员变量,状态信息等仍然存在,当然这个Activity也仍然可见,但是焦点却不在它身上。
stopped状态的Activity是完全不可见的,但是内存里面的成员变量,状态信息等仍然存在,但是也没有被销毁。
已经被销毁的Activity才处于killed状态,它的内存里面的成员变量,状态信息等都会被一并回收。
Activity生命周期的方法说明:
onCreate():
表示Activity正在被创建,通常我们在此函数中做初始化的工作,比如:绑定布局,控件,初始化数据等。
onStart():
表示Activity正在被启动,这时Activity已经被创建好,但没有出现在前台,需执行onResume()函数才可以进入到前台与用户进行交互。
onResume():
表示Activitiy已经可见,并且Activity处于运行状态,也就是Activity不止出现在了前台,而且还可以让用户点击,滑动等等操作与它进行交互。
onPause():
表示Activity正在暂停,大多数情况下,Activity执行完onPause()函数,再执行另外Activity后会继续执行onStop()函数,造成这种函数调用的原因是当前的Activity启动了另外一个Activity或者回切到上一个Activity。还有一种情况就是onPause()函数被单独执行了,并没有附带执行onStop()方法,造成这种函数调用的原因很简单,就是当前Activity里启动了类似于对话框。
onStop():
表示Activity即将停止,我们在此函数中做一些不那么耗时的轻量级回收操作。
onRestart():
表示Activity正在重新启动。一般情况下,一个存在于后台不可见的Activity变为可见状态,都会去执行onRestart()函数,然后会继续执行onStart()函数,onResume()函数出现在前台并且处于运行状态。
onDestory():
表示Activity要被销毁了。这是Activity生命周期中的最后一个阶段,我们可以在onDestory()函数中做一些回收工作和资源释放等,比如:广播接收器的注销等。
1.ActivityA启动–>onCreate()–>onStart()–>onResume()
2.点击home键回到桌面–>onPause()–>onStop()
3.再次回到原ActivityA时–>onRestart()–>onStart()–>onResume()
4.ActivityA跳转到ActivityB->onPause(A)->onCreate(B)->onStart(B)->onResume(B)->onStop(A)
5.ActivityB返回键到ActivityA-> onPause(B)->onRestart(A)->onStart(A)->onResume(A)->onStop(B)->onDestroy(B)
4.退出当前ActivityA时–>onPause()–>onStop()–>onDestroy()
1.资源相关配置发生改变导致Activity被杀死并重新创建
上图就是资源配置文件发生改变的生命周期图。
比如一个场景:我们显示一张图片,为了兼容不同设备,需要在其他目录放置不同的图片,比如drawable-mdpi and drawable-hdpi目录下。我们突然旋转屏幕,由于系统配置发生了改变,默认情况,页面会被销毁并且重新创建。
下面我们模拟下上面场景:
1.上代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String outState=null;
if(savedInstanceState!=null){
outState=savedInstanceState.getString("mBundle");
}
Log.i(TAG,"onCreate:"+outState);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG,"onSaveInstanceState");
outState.putString("mBundle","outState");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String outState=savedInstanceState.getString("mBundle");
Log.i(TAG,"onRestoreInstanceState:"+outState);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG,"onDestroy");
}
2.真机操作
竖屏(没有旋转)
此时正常启动,获取的值为null,说明只执行了onCreate方法,onSaveInstanceState和onRestoreInstanceState方法没有执行。
横屏(有旋转)
我们旋转屏幕,资源配置发生了改变,页面销毁重建。 执行循序是:onSaveInstanceState->onDestroy->onCreate->onRestoreInstanceState。
再拿横竖屏切换来讲述,但现在唯一改变的是设置了相关属性android:configChanges的值。
当我们设置Activity的android:configChanges属性为orientation或者orientation|keyboardHidden或者不设置这个属性的时候,它的生命周期会走如下流程:
当我们设置Activity的android:configChanges属性为orientation|screenSize或者orientation|screenSize|keyboardHidden
对比两图的生命周期,正常旋转是销毁重新创建页面,并执行相应生命周期的,但设置orientation|screenSize后,旋转的时候,相应生命周期是不会执行,并执行onConfigurationChanged()。
这也很好解决旋转屏幕,不重新初始化页面功能。
我们在开发项目时:
这些都需要用到启动模式来解决。
Activity的启动模式有四种:standard,singleTop,singTask和singleInstance
Standard 模式
系统的默认模式(可以不指定),在这样模式下,每启动一个Activity都会重新创建一个Activity的新实例,并且将其加入任务栈中,而且完全不会去考虑这个实例是否已存在。
我们通过图解来更清晰地了解Standard模式:
通过上图,我们可以发现,这个过程中,在standard模式下启动了三次MainActivity后,都生成了不同的新实例,并添加到同一个任务栈中。这个时候Activity的onCreate、onStart、onResume方法都会被调用。
上代码:
public class MainActivity extends AppCompatActivity {
final String TAG="MainActivityA";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG,"onCreate");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG,"onSaveInstanceState");
outState.putString("mBundle","outState");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String outState=savedInstanceState.getString("mBundle");
Log.i(TAG,"onRestoreInstanceState:"+outState);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(TAG,"onConfigurationChanged");
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG,"onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG,"onResume");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG,"onRestart");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG,"onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG,"onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG,"onDestroy");
}
public void intoMainTwo(View v){
new Thread() {
@Override
public void run() {
super.run();
try {
Thread.sleep(2000);//休眠2秒
} catch (InterruptedException e) {
e.printStackTrace();
}
Intent it=new Intent(MainActivity.this,MainActivity.class);
startActivity(it);
}
}.start();
}
}
可以看出,除了启动时执行onCreate、onStart、onResume方法,启动三次MainActivity页面,调用了三次onCreate、onStart、onResume方法。这就证明系统默认模式(standard)每启动一个Activity都会重新创建一个Activity的新实例。
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
通过此方法的参数,我们可以获取当前请求的相关信息,此时Activity的onCreate、onStart方法不会被调用,因为Activity并没有被重建。同理,我们通过图解来协助我们更清晰的理解singleTop模式:
从上图我们可以看出,当需要新创建的MainActivity位于栈顶时,MainActivity并没有重新创建。
上代码:
public class OtherActivity extends AppCompatActivity {
final String TAG="OtherOrMainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
Log.i(TAG,"onCreate_Other");
}
public void intoOtherMain(View v){
Intent it=new Intent(OtherActivity.this,MainActivity.class);
startActivity(it);
}
}
MainActivity 同上面standard代码一致。
上图可以看出,MainActivity设置为singleTop模式,MainActivity位于栈顶,启动三次MainActivity,是没有调用onCreate、onStart方法。证明MainActivity并没有重新创建。
下面我们再来看看新创建的MainActivity没有位于栈顶的情况。
上代码:
public class MainActivity extends AppCompatActivity {
final String TAG="OtherOrMainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG,"onCreate");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG,"onSaveInstanceState");
outState.putString("mBundle","outState");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String outState=savedInstanceState.getString("mBundle");
Log.i(TAG,"onRestoreInstanceState:"+outState);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(TAG,"onConfigurationChanged");
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG,"onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG,"onResume");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG,"onRestart");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG,"onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG,"onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG,"onDestroy");
}
public void intoMainTwo(View v){
Intent it=new Intent(MainActivity.this,OtherActivity.class);
startActivity(it);
}
}
public class OtherActivity extends AppCompatActivity {
final String TAG="OtherOrMainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
Log.i(TAG,"onCreate_Other");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG,"onSaveInstanceState_Other");
outState.putString("mBundle","outState");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String outState=savedInstanceState.getString("mBundle");
Log.i(TAG,"onRestoreInstanceState_Other:"+outState);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(TAG,"onConfigurationChanged_Other");
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG,"onStart_Other");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG,"onResume_Other");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG,"onRestart_Other");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG,"onPause_Other");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG,"onStop_Other");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG,"onDestroy_Other");
}
public void intoOtherMain(View v){
new Thread() {
@Override
public void run() {
super.run();
try {
Thread.sleep(2000);//休眠2秒
} catch (InterruptedException e) {
e.printStackTrace();
}
Intent it=new Intent(OtherActivity.this,MainActivity.class);
startActivity(it);
}
}.start();
}
}
看到没,这就是设置MainActivity 为栈顶模式,但MainActivity 没有在栈顶。启动三次MainActivity ,MainActivity 只执行一次onCreate方法,后两次不会重新执行onCreate方法。这种模式通常比较适用于接收到消息后显示的界面,如qq接收到消息后弹出Activity界面,如果一次来10条消息,总不能一次弹10个Activity,是吧?
public class MainActivity extends AppCompatActivity {
final String TAG="OtherOrMainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG,"onCreate");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG,"onSaveInstanceState");
outState.putString("mBundle","outState");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String outState=savedInstanceState.getString("mBundle");
Log.i(TAG,"onRestoreInstanceState:"+outState);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(TAG,"onConfigurationChanged");
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG,"onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG,"onResume");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG,"onRestart");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG,"onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG,"onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG,"onDestroy");
}
public void intoMainTwo(View v){
Intent it=new Intent(MainActivity.this,OtherActivity.class);
startActivity(it);
}
}
public class OtherActivity extends AppCompatActivity {
final String TAG="OtherOrMainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
Log.i(TAG,"onCreate_Other");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG,"onSaveInstanceState_Other");
outState.putString("mBundle","outState");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String outState=savedInstanceState.getString("mBundle");
Log.i(TAG,"onRestoreInstanceState_Other:"+outState);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(TAG,"onConfigurationChanged_Other");
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG,"onStart_Other");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG,"onResume_Other");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG,"onRestart_Other");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG,"onPause_Other");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG,"onStop_Other");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG,"onDestroy_Other");
}
public void intoOtherMain(View v){
Intent it=new Intent(OtherActivity.this,StartActivity.class);
startActivity(it);
}
}
public class StartActivity extends AppCompatActivity {
final String TAG="OtherOrMainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
Log.i(TAG,"onCreate_Start");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG,"onSaveInstanceState_Start");
outState.putString("mBundle","outState");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String outState=savedInstanceState.getString("mBundle");
Log.i(TAG,"onRestoreInstanceState_Start:"+outState);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(TAG,"onConfigurationChanged_Start");
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG,"onStart_Start");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG,"onResume_Start");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG,"onRestart_Start");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG,"onPause_Start");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG,"onStop_Start");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG,"onDestroy_Start");
}
public void intoOtherMain(View v){
Intent it=new Intent(StartActivity.this,MainActivity.class);
startActivity(it);
}
}
MainActivity->OtherActivity
OtherActivity->StartActivity
StartActivity ->MainActivity
从StartActivity ->MainActivity可以看出,MainActivity为singleTask模式,跳转至栈顶的时候,会将MainActivity以上的activity都从任务栈中移出销毁。
singleTask 模式比较适合应用的主界面activity(频繁使用的主架构)
和上面singleTask 的例子相比,只是把启动模式设置为:singleInstance ,android:launchMode=“singleInstance”。
生命周期
MainActivity->OtherActivity
OtherActivity->StartActivity
StartActivity->MainActivity
从上面的生命周期可以看出来,StartActivity再次启动MainActivity时,是没有执行onCreate方法的。
MainActivity回退
StartActivity回退
OtherActivity回退
看到没,OtherActivity回退直接销毁了OtherActivity页面,没有回到MainActivity页面,而是回到了桌面。这就证明了,设置为singleInstance模式的activity,是会独享一个Task的。
Activity-Activity
1.Intent/Bundle
//首先创建一个Bundle对象
Bundle bundle = new Bundle();
bundle.putString("data_string","数据");
bundle.putInt("data_int",6);
//然后创建一个Intent对象
Intent it= new Intent(MainActivity.this,OtherActivity.class);
it.putExtras(bundle);
startActivity(it);
2.静态内部变量
public class MainActivity extends AppCompatActivity {
final String TAG="OtherOrMainActivity";
public static Map infos=new HashMap();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG,"onCreate");
}
public void intoMainTwo(View v){
Intent it=new Intent(MainActivity.this,OtherActivity.class);
startActivity(it);
infos.put("msg","静态传值");
}
}
在OtherActivity中就直接用静态变量获取值了
String msg=MainActivity.infos.get("msg").toString();
3.全局变量
public class MyApplication extends Application {
public Map appInfos=new HashMap();
}
android:name=".MyApplication"
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG,"onCreate");
MyApplication mMyApplication=(MyApplication)getApplication();
mMyApplication.appInfos.put("mgs","全局变量");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
Log.i(TAG,"onCreate_Other");
MyApplication mMyApplication=(MyApplication)getApplication();
String msg=mMyApplication.appInfos.get("msg").toString();
Log.i(TAG,"onCreate_Other_Msg:"+msg);
}
Activity-Service
1.绑定服务的方式,利用ServiceConnection这个接口
首先我们需要在要绑定的服务中声明一个Binder类
public class MyService1 extends Service {
public String data = "";
public MyService1() {}
@Override
public IBinder onBind(Intent intent) {
return new Binder();
}
public class Binder extends android.os.Binder{
public void sendData(String data){
MyService1.this.data = data;
}
}
}
然后我们让Activity实现ServiceConnection这个接口,并且在onServiceConnected方法中获取到Service提供给Activity的Binder实例对象,通过这个对象我们就可以与Service进行通信可以通过上述代码的Binder类中的sendData()方法进行通信。
public class ServiceBindActivity extends AppCompatActivity implements ServiceConnection,View.OnClickListener {
private Button bt0,bt1,bt2;
public MyService1.Binder binder = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_bind);
bt0 = findViewById(R.id.bt0);
bt1 = findViewById(R.id.bt1);
bt2 = findViewById(R.id.bt2);
bt0.setOnClickListener(this);
bt1.setOnClickListener(this);
bt2.setOnClickListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(this);
}
//这个是服务绑定的时候调用
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
binder = (MyService1.Binder) iBinder;
}
//这个是服务解绑的时候调用
@Override
public void onServiceDisconnected(ComponentName componentName) { }
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.bt0:
//绑定服务
Intent intent = new Intent(ServiceBindActivity.this,MyService1.class);
bindService(intent,this, Context.BIND_AUTO_CREATE);
break;
case R.id.bt1:
//通过binder对象来和Service进行通信
if(binder != null)
binder.sendData("bt1");
break;
case R.id.bt2:
//通过binder对象来和Service进行通信
if(binder != null)
binder.sendData("bt2");
break;
}
}
}
2.Intent
启动和停止Service时所调用的方法都需要传入一个Intent实例对象,通过这个传入的Intent对象,我们就可以与Service进行通信。
public class ServiceStartActivity extends AppCompatActivity implements View.OnClickListener {
private Button bt0,bt1;
private Intent intent ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_start);
intent = new Intent(this, MyService2.class);
bt0 = findViewById(R.id.bt0);
bt1 = findViewById(R.id.bt1);
bt0.setOnClickListener(this);
bt1.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.bt0:
//开启服务并且传递数据
intent.putExtra("data_stirng","string数据");
startActivity(intent);
break;
case R.id.bt1:
//结束服务
stopService(intent);
break;
}
}
}
public class MyService2 extends Service {
public String data = "";
public MyService2() { }
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//得到Activity传递过来的数据
data = intent.getStringExtra("data_string");
return super.onStartCommand(intent, flags, startId);
}
}
Activity->Fragment
1.Bundle
Activity:
//首先创建一个Bundle对象
Bundle bundle = new Bundle();
bundle.putString("data_string","数据");
bundle.putInt("data_int",10);
bundle.putChar("da_char",'a');
Fragment fragment = new MyFragment1();
fragment.setArguments(bundle);
Fragment:
if(isAdded()){//这里判断是否Fragment和Activity进行了绑定
Bundle bundle = getArguments();
String data_string = bundle.getString("data_string");
String data_int = bundle.getInt("data_int");
String data_char = bundle.getChar("data_char");
}
2.直接进行方法调用
MyFragment1 myFragment1 = new MyFragment1();
myFragment.toString("传送的string数据");
好了,至此Activity的入门知识点基本讲完了,之后会分享Activity的进阶知识点和源码分析博客,敬请期待。。。