转自: https://blog.csdn.net/yuzhiqiang_1993/article/details/72675497
Activity相关
Activity是四大组件之一,应该是我们开发中接触最多的组件了吧。那么问题来了!
什么是Activity?
Activity是Android中的一个组件,提供了一个界面用于和用户交互,使用户可以在界面上进行点击、滑动等操作。
Activity的四种状态
running / paused / stopped / killed
running: 表明Activity处于活动(完全可见)状态,用户可以与屏幕进行交互,此时,Activity处于栈顶。
paused: 表明Activity处于失去焦点的状态(例如:被非全屏的的Activity覆盖),此时用户无法与该Activity进行交互。
stopped: 表明activity处于不可见的状态(例如:被另一个Activity完全覆盖)。
killed: 表明Activity被系统回收了,
Activity生命周期
首先来一张经典的图:
[图片上传失败...(image-e3b31c-1532583103079)]
Activity生命周期大致可以分为四个场景:
1.Activity启动–>onCreate()–>onStart()–onResume();
onCreate是Activity被创建的时候调用,是生命周期的第一个方法,在这里我们可以做一些初始化操作。
onStart表明Activity正在启动,此时处于用户可见状态,但是并不能与用户交互
onResume表明Activity已经处于前台状态,可以与用户交互了。
2.点击Home键–>onPause()–>onStop()
onPause:表明Activity处于paused状态,此时Activity无法与用户交互
onStop:一般在onPause后面执行,表明Activity处于完全不可见的状态。
3.点击home后再次回到程序时–>onRestart()–>onStart()–>onResume()
onRestart:表明Activity正在重新启动,从不可见状态变为可见状态
4.退出当前Activity–onPause()–>onStop()–>onDestory()
onDestory:表明Activity正在被销毁,是整个生命周期方法中的最后一个方法,在该方法中我们可以做一些资源回收的工作。
android中的进程优先级
前台/可见/服务/后台/空
前台:包含正在处于和用户交互的Activity或者是前台Activity绑定了service
可见:activity处于可见状态但不可与用户进行交互
服务:包含一个service服务的进程
后台:处于不可见的状态下(比如按了home键)
空:没有活跃的组件 知识为了缓存的目的存在的,随时都可能被系统杀掉
Android任务栈
用于存储Activity,当用户启动Activity或者退出Activity的时候,都会在栈中做一些添加或删除的操作。
Activity启动模式
1.standard
默认的启动模式,每次启动Activity的时候都会创建一个新的实例。不会复用Activity,对内存消耗较大。
2.singleTop
栈顶复用模式,如果要创建的Activity已经在栈顶的话,那么不会重新创建,直接复用,否则,仍然会重新创建。
3.singletask
栈内复用模式,如果要创建的Activity在栈内已经存在的话,不会重新创建,直接复用栈内存在的Activity,且会调用onNewIntent()方法,并且将该Activity以上的所有的Activity销毁。
4.singleInstance
单一实例,独享一个任务栈,整个手机操作系统里面只有一个实例存在。用的较少。
scheme跳转协议
android中的scheme是一种页面内跳转协议,通过自定义的scheme协议,可以方便的跳转app中的各个页面。通过scheme协议,服务端可以定制化告诉App跳转到哪个页面,可以通过通知栏消息定制化跳转页面,也可以通过H5页面跳转页面等。
Fragment相关
fragment在平时项目开发中用的也非常多,是Android3.0后引入的,起初是为了在大屏幕上更灵活的去展现ui。现在通常使用的方式是fragment+viewpager. fragment有自己的生命周期,必须依附Activity。
Fragment加载到Activity的两种方式
1.静态加载,在布局中加载
2.动态加载,在代码中加载(用的较多)
[图片上传失败...(image-2b101e-1532583103079)]
fragment经常和viewpager一起使用,不可避免的我们就会接触到FragmentPagerAdapter和FragmentStatePagerAdapter。
FragmentPagerAdapter和FragmentStatePagerAdapter有什么区别呢?
FragmentStatePagerAdapter在切换的时候会回收fragment
而FragmentPagerAdapter在切换时会将fragment与viewPager分离,并保存fragment的ui信息,
相比之下FragmentStatePagerAdapter更节省内存。所以在,在fragment比较多的时候推荐使用FragmentStatePagerAdapter。
Fragment的生命周期
Fragment是必须依附于Activity的,因此Activity的生命周期会直接影响到Fragment的生命周期。
[图片上传失败...(image-a18251-1532583103079)]
详细的生命周期我们来看下面这张图:
[图片上传失败...(image-cd12b0-1532583103079)]
由图片我们可以看整个fragment和Activity的生命周期执行顺序
fragment从创建到创建完成:
1.调用fragment中的onAttach() fragment与Activity发生关联时调用
2.调用fragment中的onCreate() 创建fragment时调用
3.调用fragment中的onCreateView() 绘制fragment视图时调用
4.调用fragment中的onViewCreated() 界面绘制完成后调用
5.调用activity中的onCreate() activity创建了
6.调用fragment中的onActivityCreated() 在activity的onCreate()方法之后调用,表明activity已经绘制完成
7.调用activity中的onstart() 表明activity可见了
8.调用fragment中的onstart() activity可见后调用fragment中的onstart(),表明fragment也可见了
9.调用activity的onresume()方法 表明activity可以跟用户交互了
10.调用fragment的onResume()方法 此时,fragment也可以与用户进行交互了,到此为止,fragment完全初始化完毕了。
fragment的销毁过程:
1.调用fragment中的onPause() 此时fragment不可与用户交互
2.调用activity中的onPause() 此时activity不可与用户交互
3.调用fragment中的onStop() 此时fragment不可见
4.调用activity中的onStop() 此时activity不可见
5.调用fragment中的onDestoryView() fragment视图被移除调用
6.调用fragment中的onDestory() fragment销毁时调用
7.调用fragment中的onDetach() fragment与activity解除关联时调用
8.调用activity中的ondDestory() activity销毁
fragment通信
1.fragment调用Activity中的方法
通过getActivity()调用
2.在Activity中调用Fragment中的方法
需要在fragment类中定义一个接口并在Activity中实现它。Fragment在onAttach()回调函数中获取接口的具体实现的对象。然后,fragment就可以调用接口中的方法实现与Activity的通信。
3.在Fragment中调Fragment中的方法
通过getSupportFragmentManager().findFragmentById()
FragmentManager中的add,remove和replace
一般我们两种模式,一种是将fragment添加(add)到容器中,控制其隐藏和显示。这种模式不会销毁fragment。
另一种就是替换(replace)这种方法会把之前的fragment销毁掉。
Service相关
service是四大组件之一,用的地方也很多。可以在后台执行一些逻辑。
什么是Service
Service是一种能在后台执行耗时任务的没有界面显示的组件。需要注意的是Service和BroadCastReceiver都是运行在主线程的,所以,Service本身不能做耗时操作,而是通过子线程去完成!
Service和Thread的区别
详细可以看这篇博客service和thread的区别 讲的非常仔细。
在这里做个总结:
Thread和Service实际上是没有任何关系,只不过因为字面上的意思,我们可能会误解为Service可以执行耗时任务的,实际上Service是运行在主线程上的,也就是说,Service本身并不能做耗时操作,一般都是在Service中启线程去执行耗时任务。
Thread是程序执行的最小单元,是独立与Activity运行的,也就是说,如果我们在Activity中启线程去执行任务,即使这个activity被销毁了,该任务也会继续执行。
而Service是Android中一种机制,在一些运行在后台的不需要界面的地方可以使用Service。
Service的生命周期
onbind/onCreate/onStartCommand/ondestory
onBind(): 该方法返回的是一个IBinder接口,当我们使用bindService的时候才会被调用
onCreate(): 服务首次创建时调用,注意,只有service第一个被创建时才会调用
onStartCommand(): 每次调用startService的时候都会执行该方法,该方法有一个int类型的返回值
[图片上传失败...(image-fc6846-1532583103078)]
分别是:START_STICKY、START_NOT_STICKY、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY。
START_STICKY:”粘性的”,如果service进程被意外kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
onDestory(): 服务销毁时调用,在这里可以做一些资源回收操作。
Service的两种启动方式
startService 和 bindService
startService
1.定义一个类继承自Service
2.在清单配置文件中声明
3.使用Context.startService(Intent)启动Service
4.调用Context.stopService(Intent)停止Service
Intent intent = new Intent();
intent.setClass(activity, UpdateApkService.class);
activity.startService(intent);//开启服务
执行startService时,Service会经历onCreate->onStartCommand。当执行stopService时,直接调用onDestroy方法。调用者如果没有stopService,那么即使Activity被销毁了,Service也会继续执行,下次调用者再起来仍然可以stopService。
bindService
1.创建一个类继承自Service,并在类中创建一个实现IBinder接口的实例对象并提供公共方法。
/*这里定义一个类 用于返回Service*/
public class MyBinder extends Binder {
public MyService getService() {
return MyService.this;
}
}
/*提供一个公共方法*/
public Date getTime(){
return new Date();
}
2.在onBind()中返回自定义的IBinder实例
private MyBinder myBinder=new MyBinder();
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
3.在需要调用的地方,从onServiceConnected中获取IBinder实例并调用公共方法
sc = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("aaa","onServiceConnected");
MyService.MyBinder myBinder = (MyService.MyBinder) service;
Date date = ((MyService.MyBinder) service).getService().getTime();
Log.i("aaa",date.toString());
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
Intent intent = new Intent(this, MyService.class);
bindService(intent, sc, BIND_AUTO_CREATE);
执行bindService时,Service会经历onCreate->onBind。这个时候调用者和Service绑定在一起。调用者调用unbindService方法或者调用者Context不存在了(如Activity被finish了),Service就会调用onUnbind->onDestroy。这里所谓的绑定在一起就是说两者共存亡了。
BroadcastReceiver
四大组件之一,在Android中,Broadcast是一种广泛运用在应用程序之间传输信息的机制,Android中我们要发送的是一个intent,intent可易携带我们需要传输的数据。
广播的使用场景
1.同一app中不同组件之间的数据传递
2.不同app之间组件的数据传递
广播的种类
1.普通广播 Context.sendBroadcast
2.有序广播 Context.sendOrderedBroadcast 根据优先级传播,优先级高的接收器和一阻止继续传播活修改数据
3.本地广播 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this); lbm.sendBroadcast(new Intent(LOCAL_ACTION)); 只会在应用内部传播,相对来说数据安全。
广播的注册方式
1.静态注册 在清单配置文件中声明,即使进程被杀死,该广播仍然运行
2.动态注册 在代码中注册,受activity生命周期的影响。
MyReceiver receiver = new MyReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.MY_BROADCAST");
registerReceiver(receiver, filter);
内部实现机制
1.自定义BroadcastReceiver,重写onReceive()方法
2.通过Binder机制向AMS(Activity Manager Service)进行注册
3.广播发送者通过Binder机制向AMS发送广播
4.AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadCastReceiver相应的消息循环队列中
5.消息循环执行拿到广播,回调BroadCastReceiver中的onReceive()方法。
LocalBroadcastManager
1.使用LocalBroadcastManager发送的广播只能在app内部传播,因此数据传输很安全。
2.比系统广播更加高效,底层是通过Handler发送message实现的。