01.Android之基础组件问题
2019-01-07
5110
简介:
目录介绍
1.0.0.1 说下Activity的生命周期?屏幕旋转时生命周期?异常条件会调用什么方法?
1.0.0.2 后台的Activity被系统回收怎么办?说一下onSaveInstanceState()和onRestoreInstanceState()方法特点?
1.
目录介绍
- 1.0.0.1 说下Activity的生命周期?屏幕旋转时生命周期?异常条件会调用什么方法?
- 1.0.0.2 后台的Activity被系统回收怎么办?说一下onSaveInstanceState()和onRestoreInstanceState()方法特点?
- 1.0.0.3 如何避免配置改变时Activity重建?优先级低的Activity在内存不足被回收后怎样做可以恢复到销毁前状态?
- 1.0.0.4 app切换到后台,当前activity会走onDestory方法吗?一般在onstop方法里做什么?什么情况会导致app会被杀死?
- 1.0.0.5 Activity的启动过程是有几种方式?从桌面launcher上点击应用图标会干啥,调用startActivty()又会做什么?
- 1.0.0.6 说下Activity的四种启动模式?singleTop和singleTask的区别以及应用场景?任务栈的作用是什么?
- 1.0.0.7 两个Activity之间怎么传递数据?intent和bundle有什么区别?为什么有了intent还要设计bundle?
- 1.0.0.8 知道哪些Activity启动模式的标记位?flag是干什么用的,什么时候用到?
- 1.0.1.0 同一程序不同的Activity是否可以放在不同的Task任务栈中?
- 1.0.1.1 介绍一下Service,启动Service有几种方式,生命周期是怎样的?说一下onStartCommand()的作用?service如何杀不死?
- 1.0.1.2 一个Activty先start一个Service后,再bind时会回调什么方法?此时如何做才能回调Service的destory()方法?
- 1.0.1.3 bindService是一个异步的过程吗?绑定service大概需要经历那些过程?
- 1.0.1.4 是否能在Service进行耗时操作?如果非要可以怎么做,如何避免service线程卡顿?service里面可以弹土司吗?
- 1.0.1.5 Activity如何与Service通信?Service的生命周期与启动方法有什么区别?
- 1.0.2.0 是否了解ActivityManagerService,它发挥什么作用,说一下AMS启动流程?
- 1.0.2.1 Android中哪些事件需要用到广播?广播的生命周期是怎样的?
- 1.0.2.3 广播有几种形式?他们分别有什么特点,如何使用广播?广播是怎么实现不同进程之间通信的?
- 1.0.2.8 Fragment与Activity之间是如何传值的?Fragment与Fragment之间是如何传值的?
- 1.0.2.9 Activity创建Fragment的方式是什么?FragmentPageAdapter和FragmentPageStateAdapter的区别?
- 1.0.3.0 fragment 特点?说一下Fragment的生命周期?如何解决getActivity为null的异常问题?
- 1.0.3.1 在fragment中为什么有时getActivity()会为null?Fragment试图为什么有的时候会重叠,怎么产生的,又如何解决?
- 1.0.3.2 为什么fragment传递数据不用构造方法传递?FragmentManager , add 和 replace 有什么区别?
- 1.0.3.9 Activitiy启动流程中performLaunchActivity的作用?
- 1.0.4.0 Intent是什么?Intent可以传递哪些数据?传递对象的时候为什么要实例化?
- 1.0.4.1 mipmap系列中xxxhdpi、xxhdpi、xhdpi、hdpi、mdpi和ldpi存在怎样的关系?
- 1.0.4.2 res目录和assets目录的区别?R文件是如何生成的,主要有什么作用?
- 1.0.4.3 Context是什么?Context有哪些类型,分别作用是什么?Context下有哪些子类?哪些场景只能用activity上下文?
- 1.0.4.4 ActivityThread的main()的流程大概是怎么样的?
- 1.0.5.0 序列化的方式有哪些?效率对比有何优势?如何做性能上分析的?
- 1.0.5.9 界面的刷新为什么需16.6ms?画面的显示需要哪些步骤?界面保持不变时还会16.6ms刷新一次屏幕吗?
- 1.0.6.0 Android中日志级别有哪几种?开发中需要注意什么问题,打印日志源码分析原理是什么?
好消息
- 博客笔记大汇总【15年10月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计500篇[近100万字],将会陆续发表到网上,转载请注明出处,谢谢!
- 链接地址:https://github.com/yangchong211/YCBlogs
- 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议,万事起于忽微,量变引起质变!所有的笔记将会更新到GitHub上,同时保持更新,欢迎同行提出或者push不同的看法或者笔记!
1.0.0.1 说下Activity的生命周期?屏幕旋转时生命周期?异常条件会调用什么方法?
1.0.0.2 后台的Activity被系统回收怎么办?说一下onSaveInstanceState()和onRestoreInstanceState()方法特点?
1.0.0.3 如何避免配置改变时Activity重建?优先级低的Activity在内存不足被回收后怎样做可以恢复到销毁前状态?
1.0.0.4 app切换到后台,当前activity会走onDestory方法吗?一般在onstop方法里做什么?什么情况会导致app会被杀死,这时候会走onDestory吗?
1.0.0.5 Activity的启动过程是有几种方式?从桌面launcher上点击应用图标会干啥,调用startActivty()又会做什么?
1.0.0.6 说下Activity的四种启动模式?singleTop和singleTask的区别以及应用场景?任务栈的作用是什么?
1.0.0.7 两个Activity之间怎么传递数据?intent和bundle有什么区别?为什么有了intent还要设计bundle?
-
两个Activity之间怎么传递数据?
- 基本数据类型可以通过Intent传递数据
-
把数据封装至intent对象中
Intent intent = new Intent(content, MeActivity.class);
intent.putExtra("goods_id", goods_id);
content.startActivity(intent);
- 把数据封装至bundle对象中技术博客大总结
-
把bundle对象封装至intent对象中
Bundle bundle = new Bundle();
bundle.putString("malename", "李志");
intent.putExtras(bundle);
startActivity(intent);
-
intent和bundle有什么区别?
-
Intent传递数据和Bundle传递数据是一回事,Intent传递时内部还是调用了Bundle。
public @NonNull Intent putExtra(String name, String value) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putString(name, value);
return this;
}
-
为什么有了intent还要设计bundle?
-
两者比较
- Bundle只是一个信息的载体,内部其实就是维护了一个Map。
- Intent负责Activity之间的交互,内部是持有一个Bundle的。
-
bundle使用场景
- Fragment之间传递数据;比如,某个Fragment中点击按钮弹出一个DialogFragment。最便捷的方式就是通过Fragment.setArguments(args)传递参数。
public static void showFragmentDialog(String title, String content, boolean is_open, AppCompatActivity activity) {
ServiceDialogFragment mainDialogFragment = new ServiceDialogFragment();
Bundle bundle = new Bundle();
bundle.putString("title", title);
bundle.putString("content", content);
bundle.putBoolean("is_open",is_open);
mainDialogFragment.setArguments(bundle);
mainDialogFragment.show(activity.getSupportFragmentManager());
}
@Override
public void onCreate(Bundle savedInstanceState) {
setLocal(Local.CENTER);
super.onCreate(savedInstanceState);
Bundle bundle = getArguments();
if (bundle != null) {
title = bundle.getString("title");
content = bundle.getString("content");
is_open = bundle.getBoolean("is_open");
}
}
1.0.0.8 知道哪些Activity启动模式的标记位?flag是干什么用的,什么时候用到?
-
常见的标记为:
- FLAG_ACTIVITY_SINGLE_TOP:对应singleTop启动模式
- FLAG_ACTIVITY_NEW_TASK :对应singleTask模式
1.0.1.0 同一程序不同的Activity是否可以放在不同的Task任务栈中?
1.0.1.1 介绍一下Service,启动Service有几种方式,生命周期是怎样的?说一下onStartCommand()的作用?service如何杀不死?
-
Service分为两种
- 本地服务,属于同一个应用程序,通过startService来启动或者通过bindService来绑定并且获取代理对象。如果只是想开个服务在后台运行的话,直接startService即可,如果需要相互之间进行传值或者操作的话,就应该通过bindService。
- 远程服务(不同应用程序之间),通过bindService来绑定并且获取代理对象。
-
对应的生命周期如下:
- context.startService() ->onCreate()- >onStartCommand()->Service running--调用context.stopService() ->onDestroy()
- context.bindService()->onCreate()->onBind()->Service running--调用>onUnbind() -> onDestroy()
-
注意
- Service默认是运行在main线程的,因此Service中如果需要执行耗时操作(大文件的操作,数据库的拷贝,网络请求,文件下载等)的话应该在子线程中完成。
-
Service生命周期解释技术博客大总结
- onCreate():服务第一次被创建时调用
- onStartComand():服务启动时调用
- onBind():服务被绑定时调用
- onUnBind():服务被解绑时调用
- onDestroy():服务停止时调用
- 说一下onStartCommand()的作用?
-
service如何杀不死?
- 1.onStartCommand方法,返回START_STICKY(粘性)当service因内存不足被kill,当内存又有的时候,service又被重新创建
- 2.设置优先级,在服务里的ondestory里发送广播 在广播里再次开启这个服务,双进程守护
1.0.1.2 一个Activty先start一个Service后,再bind时会回调什么方法?此时如何做才能回调Service的destory()方法?
-
关于service中onDestroy()什么时候会被执行?
- 当调用了startService()方法后,又去调用stopService()方法,这时服务中的onDestroy()方法就会执行,表示服务已经销毁了。
- 类似地,当调用了 bindService()方法后,又去调用unbindService()方法,onDestroy()方法也会执行,这两种情况都很好理解。
-
一个Activty先start一个Service后,再bind时会回调什么方法?
-
先start后bind操作service,此时如何做才能回调Service的destory()方法?
- 完全有可能对一个服务既调用了startService()方法,又调用了bindService()方法的,这种情况下该如何才能让服务销毁掉呢?根据Android系统的机制,一个服务只要被启动或者被绑定了之后,就会一直处于运行状态,必须要让以上两种条件同时不满足,服务才能被销毁。
- 这种情况下要同时调用stopService()和unbindService()方法,onDestroy()方法才会执行这样就把服务的生命周期完整地走了一遍。技术博客大总结
1.0.1.3 bindService是一个异步的过程吗?绑定service大概需要经历那些过程?
1.0.1.4 是否能在Service进行耗时操作?如果非要可以怎么做,如何避免service线程卡顿?service里面可以弹土司吗?
1.0.1.5 Activity如何与Service通信?Service的生命周期与启动方法有什么区别?
-
Activity如何与Service通信?
-
方法一:
- 添加一个继承Binder的内部类,并添加相应的逻辑方法。重写Service的onBind方法,返回我们刚刚定义的那个内部类实例。Activity中创建一个ServiceConnection的匿名内部类,并且重写里面的onServiceConnected方法和onServiceDisconnected方法,这两个方法分别会在活动与服务成功绑定以及解除绑定的时候调用,在onServiceConnected方法中,我们可以得到一个刚才那个service的binder对象,通过对这个binder对象进行向下转型,得到我们那个自定义的Binder实例,有了这个实例,做可以调用这个实例里面的具体方法进行需要的操作了
-
方法二
- 通过BroadCast(广播)的形式,当我们的进度发生变化的时候我们发送一条广播,然后在Activity的注册广播接收器,接收到广播之后更新视图
1.0.2.0 是否了解ActivityManagerService,它发挥什么作用,说一下AMS启动流程?
1.0.2.1 Android中哪些事件需要用到广播?广播的生命周期是怎样的?
-
Android中哪些事件需要用到广播?
- Android中:系统在运行过程中,会产生会多事件,那么某些事件产生时,比如:电量改变、收发短信、拨打电话、屏幕解锁、开机,系统会发送广播,只要应用程序接收到这条广播,就知道系统发生了相应的事件,从而执行相应的代码。使用广播接收者,就可以收听广播
-
广播的生命周期是怎样的?
- a.广播接收者的生命周期非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁;
- b.广播接收者中不要做一些耗时的工作,否则会弹出 Application No Response错误对话框;
- c.最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉;
- d.耗时的较长的工作最好放在服务中完成;
1.0.2.3 广播有几种形式?他们分别有什么特点,如何使用广播?广播是怎么实现不同进程之间通信的?
-
广播有几种形式
- 普通广播:一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们接收的先后是随机的。
- 有序广播:一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递,所以此时的广播接收器是有先后顺序的,且优先级(priority)高的广播接收器会先收到广播消息。有序广播可以被接收器截断使得后面的接收器无法收到它。
- 本地广播:发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收本应用程序发出的广播。
- 粘性广播:这种广播会一直滞留,当有匹配该广播的接收器被注册后,该接收器就会收到此条广播。
-
广播的两种注册形式技术博客大总结
- 广播的注册有两种方法:一种在活动里通过代码动态注册,另一种在配置文件里静态注册。两种方式的相同点是都完成了对接收器以及它能接收的广播值这两个值的定义;不同点是动态注册的接收器必须要在程序启动之后才能接收到广播,而静态注册的接收器即便程序未启动也能接收到广播,比如想接收到手机开机完成后系统发出的广播就只能用静态注册了。
-
动态注册
-
需要使用广播接收者时,执行注册的代码,不需要时,执行解除注册的代码。安卓中有一些广播接收者,必须使用代码注册,清单文件注册是无效的。
public class MainActivity extends Activity {
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "network changes",Toast.LENGTH_SHORT).show();
}
}
}
-
静态注册
- 可以使用清单文件注册。广播一旦发出,系统就会去所有清单文件中寻找,哪个广播接收者的action和广播的action是匹配的,如果找到了,就把该广播接收者的进程启动起来。
1.0.2.8 Fragment与Activity之间是如何传值的?Fragment与Fragment之间是如何传值的?
1.0.2.9 Activity创建Fragment的方式是什么?FragmentPageAdapter和FragmentPageStateAdapter的区别?
1.0.3.0 fragment 特点?说一下Fragment的生命周期?如何解决getActivity为null的异常问题?
-
fragment 特点
- Fragment可以作为Activity界面的一部分组成出现;
- 可以在一个Activity中同时出现多个Fragment,并且一个Fragment也可以在多个Activity中使用;
- 在Activity运行过程中,可以添加、移除或者替换Fragment;
- Fragment可以响应自己的输入事件,并且有自己的生命周期,它们的生命周期会受宿主Activity的生命周期影响。
-
Fragment从创建到销毁整个生命周期中涉及到的方法依次为:
-
如何解决getActivity为null的异常问题技术博客大总结
@Override
public void onAttach(Context context) {
super.onAttach(context);
activity = (PhoneNumActivity) context;
}
@Override
public void onDetach() {
super.onDetach();
activity = null;
}
1.0.3.1 在fragment中为什么有时getActivity()会为null?Fragment试图为什么有的时候会重叠,怎么产生的,又如何解决?
1.0.3.2 为什么fragment传递数据不用构造方法传递?FragmentManager , add 和 replace 有什么区别?
1.0.3.9 Activitiy启动流程中performLaunchActivity的作用?Activity启动流程中handleResumeActivity的作用?
-
Activitiy启动流程中performLaunchActivity的作用?
- 从ActivityClientRecord中获取到待启动的Activity的组件信息
- 使用类加载器创建Activity对象
- 通过LoadedApk的方法创建Applicayiton对象,该对象唯一,不会重复创建。
- 会创建ContextImpl并且建立Context和Activity的联系,以及创建PhoneWindow,建立Window和Activity的联系。
- 调用Activity的onCreate()
-
Activity启动流程中handleResumeActivity的作用?
- 执行onStart()、onResume()—利用Instrucmentation
- 获取Window
- 创建DecorView、设置为不可见INVISIBLE、建立DecorView和Activity的联系。
- 获取Activity的WindowManager
- 调用WindowManager.addView(decorView, ...)将DecorView添加到WM中,完成显示的工作。

-
何时将DecorView设置为VISIBLE?并且显示出来?技术博客大总结
- 也是在handleResumeActivity中
- 现将DecorView设置为不可见
- wm.addView(): 将DecorView添加到Window总
- 然后执行makeVisible让DecorView可见

1.0.4.0 Intent是什么?Intent可以传递哪些数据?传递对象的时候为什么要实例化?
1.0.1.2 Activity如与Service通信?Service的生命周期与启动方法由什么区别?
可以通过bindService的方式,先在Activity里实现一个ServiceConnection接口,并将该接口传递给bindService()方法,在ServiceConnection接口的onServiceConnected()方法
里执行相关操作。
Service的生命周期与启动方法由什么区别?
startService():开启Service,调用者退出后Service仍然存在。
bindService():开启Service,调用者退出后Service也随即退出。
Service生命周期:
只是用startService()启动服务:onCreate() -> onStartCommand() -> onDestory
只是用bindService()绑定服务:onCreate() -> onBind() -> onUnBind() -> onDestory
同时使用startService()启动服务与bindService()绑定服务:onCreate() -> onStartCommnad() -> onBind() -> onUnBind() -> onDestory
1.1.0.4 广播有哪些注册方式?有什么区别?广播发送和接收原理是什么[binder如何运作的]?
1.0.4.1 mipmap系列中xxxhdpi、xxhdpi、xhdpi、hdpi、mdpi和ldpi存在怎样的关系?
- 表示不同密度的图片资源,像素从高到低依次排序为xxxhdpi>xxhdpi>xhdpi>hdpi>mdpi>ldpi,根据手机的dpi不同加载不同密度的图片
1.0.4.2 res目录和assets目录的区别?
- assets:不会在 R文件中生成相应标记,存放到这里的资源在打包时会打包到程序安装包中。(通过 AssetManager 类访问这些文件)
- res:会在 R 文件中生成 id标记,资源在打包时如果使用到则打包到安装包中,未用到不会打入安装包中。
- res/anim:存放动画资源
- res/raw:和 asset下文件一样,打包时直接打入程序安装包中(会映射到 R文件中)
1.0.4.3 Context是什么?Context有哪些类型,分别作用是什么?Context下有哪些子类?哪些场景只能用activity上下文?
-
Context是什么?
- Context是一个抽象基类。在翻译为上下文,也可以理解为环境,是提供一些程序的运行环境基础信息。
-
Context有哪些类型,分别作用是什么?
- Context下有两个子类,ContextWrapper是上下文功能的封装类,而ContextImpl则是上下文功能的实现类。
- ContextWrapper又有三个直接的子类,ContextThemeWrapper、Service和Application。其中,ContextThemeWrapper是一个带主题的封装类,而它有一个直接子类就是Activity,所以Activity和Service以及Application的Context是不一样的,只有Activity需要主题,Service不需要主题。
-
Context下有哪些子类,主要是干什么的?
- Context一共有三种类型,分别是Application、Activity和Service。
- 这三个类虽然分别各种承担着不同的作用,但它们都属于Context的一种,而它们具体Context的功能则是由ContextImpl类去实现的,因此在绝大多数场景下,Activity、Service和Application这三种类型的Context都是可以通用的。
- 不过有几种场景比较特殊,比如启动Activity,还有弹出Dialog。出于安全原因的考虑,Android是不允许Activity或Dialog凭空出现的,一个Activity的启动必须要建立在另一个Activity的基础之上,也就是以此形成的返回栈。而Dialog则必须在一个Activity上面弹出(除非是系统级别吐司),因此在这种场景下,我们只能使用Activity类型的Context,否则将会出错。
1.0.4.4 ActivityThread的main()的流程大概是怎么样的?
1.0.5.0 序列化的方式有哪些?效率对比有何优势?如何做性能上分析的?
-
序列化的方式有哪些
-
Parcelable
- Parcelable是Android特有的一个实现序列化的接口,在Parcel内部包装了可序列化的数据,可以在Binder中自由传输。序列化的功能由writeToParcel方法来完成,最终通过Parcel的一系列write方法完成。反序列化功能由CREAOR来完成,其内部标明了如何创建序列化对象和数组,并通过Parcel的一系列read方法来完成反序列化的过程。
-
Serializable
- Serializable是Java提供的一个序列化接口,是一个空接口,用于标示对象是否可以支持序列化,通过ObjectOutputStrean及ObjectInputStream实现序列化和反序列化的过程。注意可以为需要序列化的对象设置一个serialVersionUID,在反序列化的时候系统会检测文件中的serialVersionUID是否与当前类的值一致,如果不一致则说明类发生了修改,反序列化失败。因此对于可能会修改的类最好指定serialVersionUID的值。
1.0.5.9 界面的刷新为什么需16.6ms?画面的显示需要哪些步骤?界面保持不变时还会16.6ms刷新一次屏幕吗?
1.0.6.0 Android中日志级别有哪几种?开发中需要注意什么问题,打印日志源码分析原理是什么?
-
Android中日志级别有哪几种?
- 1.Log.v 的输出颜色为黑色的,输出大于或等于VERBOSE日志级别的信息,也就是可见级别,一般是最低的信息提示
- 2.Log.d的输出颜色是蓝色的,也就是调式级别,一般不会中止程序,一般是程序员为了调试而打印的log
- 3.Log.i的输出为绿色,输出大于或等于INFO日志级别的信息,也就是信息界级别,不会中止程序,一般是系统中执行操作的信息提示
- 4.Log.w的输出为橙色, 输出大于或等于WARN日志级别的信息,也就是警告级别,一般不会中止程序,但是可能会影响程序执行结果
- 5.Log.e的输出为红色,仅输出ERROR日志级别的信息,也就是错误级别,一般会中止程序运行,是最严重的Log级别。
-
解释:
- verbose
- debug调试
- info信息
- warn警告
- error误差
- 通过查看源代码我们发现Log类中所有的静态日志方法Log.v(),Log.d(),Log.i(),Log.w(),Log.e()等方法都是底层都是调用了println方法,然后在源码中查看,其实其内部调用的是println_native方法,也就是通过JNI调用底层的c++输出日志。
关于其他内容介绍
01.关于博客汇总链接
02.关于我的博客
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。