Android中Theme类可以继承?
不可以
解析:我们先看一下AndroidManifest.xml文件,里面有这么一行代码
android:theme="@style/AppTheme"
即对主题样式的指定、设置,接下来进入styles.xml文件
<style name="AppTheme1" parent="Theme.AppCompat.Light">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="Animation" />
<style name="Animation.Dialog">
<item name="windowEnterAnimation">@anim/dialog_enter</item>
<item name="windowExitAnimation">@anim/dialog_exit</item>
</style>
这里的样式代码,可以分为两种,一种是使用parent,代表该样式来自哪里?一般在java里,我们都说继承,parent即对应父类,另一种是使用已有的style名字后直接加.来表示(这种是自定义的style),这么看来,似乎Theme类是可以继承的,我就是这样认识错的。下面我们再从用代码设置主题的方面来看一下,
直接在activity里就可以设置setTheme(); 我们点进去
@Override
public void setTheme(@StyleRes final int resid) {
super.setTheme(resid);
// Keep hold of the theme id so that we can re-set it later if needed
mThemeId = resid;
}
我们来看一下这个mThemeId是如何使用的(只看重点,感兴趣自己看源码)
if (Build.VERSION.SDK_INT >= 23) {
onApplyThemeResource(getTheme(), mThemeId, false);
} else {
setTheme(mThemeId);
}
这里就对6.0上下进行了不同的方法设置,我们先看6.0以上的系统
@Override
protected void onApplyThemeResource(Resources.Theme theme, @StyleRes int resid,
boolean first) {
if (mParent == null) {
super.onApplyThemeResource(theme, resid, first);
} else {
try {
theme.setTo(mParent.getTheme());
} catch (Exception e) {
// Empty
}
theme.applyStyle(resid, false);
}
// Get the primary color and update the TaskDescription for this activity
TypedArray a = theme.obtainStyledAttributes(
com.android.internal.R.styleable.ActivityTaskDescription);
if (mTaskDescription.getPrimaryColor() == 0) {
int colorPrimary = a.getColor(
com.android.internal.R.styleable.ActivityTaskDescription_colorPrimary, 0);
if (colorPrimary != 0 && Color.alpha(colorPrimary) == 0xFF) {
mTaskDescription.setPrimaryColor(colorPrimary);
}
}
int colorBackground = a.getColor(
com.android.internal.R.styleable.ActivityTaskDescription_colorBackground, 0);
if (colorBackground != 0 && Color.alpha(colorBackground) == 0xFF) {
mTaskDescription.setBackgroundColor(colorBackground);
}
final int statusBarColor = a.getColor(
com.android.internal.R.styleable.ActivityTaskDescription_statusBarColor, 0);
if (statusBarColor != 0) {
mTaskDescription.setStatusBarColor(statusBarColor);
}
final int navigationBarColor = a.getColor(
com.android.internal.R.styleable.ActivityTaskDescription_navigationBarColor, 0);
if (navigationBarColor != 0) {
mTaskDescription.setNavigationBarColor(navigationBarColor);
}
a.recycle();
setTaskDescription(mTaskDescription);
}
这里面看着是否和自定义view有点相似,大概就是一层层抠出来,像我们前面写的style有parent,点到为止,这里不是研究这个问题。6.0以下的,就直接看他的父类方法
@Override
public void setTheme(int resid) {
if (mThemeResource != resid) {
mThemeResource = resid;
initializeTheme();
}
}
发现,mThemeResource的使用和6.0以上类似(不做重点),继续initializeTheme(初始化主题)
private void initializeTheme() {
final boolean first = mTheme == null;
if (first) {
mTheme = getResources().newTheme();
final Resources.Theme theme = getBaseContext().getTheme();
if (theme != null) {
mTheme.setTo(theme);
}
}
onApplyThemeResource(mTheme, mThemeResource, first);
}
重点出现了,Theme是用final修饰的,很明显不能被继承。
进程的分类
前台进程
用户当前操作所必需的进程。如果一个进程满足以下任一条件,即视为前台进程:
托管用户正在交互的 Activity(已调用 Activity 的 onResume() 方法)
托管某个 Service,后者绑定到用户正在交互的 Activity
托管正在“前台”运行的 Service(服务已调用 startForeground())
托管正执行一个生命周期回调的 Service(onCreate()、onStart() 或 onDestroy())
托管正执行其 onReceive() 方法的 BroadcastReceiver
通常,在任意给定时间前台进程都为数不多。只有在内存不足以支持它们同时继续运行这一万不得已的情况下,系统才会终止它们。 此时,设备往往已达到内存分页状态,因此需要终止一些前台进程来确保用户界面正常响应。
可见进程
没有任何前台组件、但仍会影响用户在屏幕上所见内容的进程。 如果一个进程满足以下任一条件,即视为可见进程:
托管不在前台、但仍对用户可见的 Activity(已调用其 onPause() 方法)。例如,如果前台 Activity 启动了一个对话框,允许在其后显示上一 Activity,则有可能会发生这种情况。
托管绑定到可见(或前台)Activity 的 Service。
可见进程被视为是极其重要的进程,除非为了维持所有前台进程同时运行而必须终止,否则系统不会终止这些进程。
服务进程
正在运行已使用 startService() 方法启动的服务且不属于上述两个更高类别进程的进程。尽管服务进程与用户所见内容没有直接关联,但是它们通常在执行一些用户关心的操作(例如,在后台播放音乐或从网络下载数据)。因此,除非内存不足以维持所有前台进程和可见进程同时运行,否则系统会让服务进程保持运行状态。
后台进程
包含目前对用户不可见的 Activity 的进程(已调用 Activity 的 onStop() 方法)。这些进程对用户体验没有直接影响,系统可能随时终止它们,以回收内存供前台进程、可见进程或服务进程使用。 通常会有很多后台进程在运行,因此它们会保存在 LRU (最近最少使用)列表中,以确保包含用户最近查看的 Activity 的进程最后一个被终止。如果某个 Activity 正确实现了生命周期方法,并保存了其当前状态,则终止其进程不会对用户体验产生明显影响,因为当用户导航回该 Activity 时,Activity 会恢复其所有可见状态。 有关保存和恢复状态的信息,请参阅 Activity文档。
空进程
不含任何活动应用组件的进程。保留这种进程的的唯一目的是用作缓存,以缩短下次在其中运行组件所需的启动时间。 为使总体系统资源在进程缓存和底层内核缓存之间保持平衡,系统往往会终止这些进程。
SimpleAdapter类支持的绑定view类型
if (!bound) {
//该view是否实现checkable接口
if (v instanceof Checkable) {
if (data instanceof Boolean) {
((Checkable) v).setChecked((Boolean) data);
//该view是否是TextView
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these
// ifs since a lot of views are TextViews (e.g. CheckBoxes).
setViewText((TextView) v, text);
} else {
throw new IllegalStateException(v.getClass().getName() +
" should be bound to a Boolean, not a " +
(data == null ? "<unknown type>" : data.getClass()));
}
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these
// ifs since a lot of views are TextViews (e.g. CheckBoxes).
setViewText((TextView) v, text);
//该view是否是ImageView
} else if (v instanceof ImageView) {
if (data instanceof Integer) {
setViewImage((ImageView) v, (Integer) data);
} else {
setViewImage((ImageView) v, text);
}
} else {
throw new IllegalStateException(v.getClass().getName() + " is not a " +
" view that can be bounds by this SimpleAdapter");
}
}
以上源码很明显能看出来使用SimpleAdapter作为适配器时,支持三种类型的 View,而且是按照如下顺序进行匹配: 实现Checkable接口 、TextView、 ImageView,但面试或笔试的时候,问你的不一定是这么明显,比如CompoundButton是否支持?它支持是因为它实现了checkable接口还是TextView的子类?因为这是按照顺序判断的,所以CompoundButton实现了Checkable接口,所以被SimpleAdapter支持,虽然它同样可以在第二个判断里通过,但不考虑。
ANR和FC
ANR(Application Not Respone):程序无响应,有可能程序会再次响应
出现条件:1.当用户输入事件5s内没有得到响应,将弹出ANR对话框 2.广播接收者的onReceive()执行时间超过10s
FC(Force close):程序抛出异常,会强制退出
出现条件:Error 、OOM,内存溢出 、StackOverFlowError 、Runtime,比如说空指针异常
关于这两种情况如何避免,以后再说,这里主要是要说下正确理解和区分这两种情况。