Android基础与底层机制
1、数据库的操作类型有哪些,如何导入外部数据库?
1、使用数据库的方式:
a、openOrCreateDatabase(String path)。
b、继承SqliteOpenHelper 类对数据库及其版本进行管理(onCreate,onUpgrade),使用getWriteableDatabase()或getReadableDatabase()打开数据库,数据库不存在则创建。
2、操作的类型:增删改查CRUD
a、直接操作SQL语句:SqliteDatabase.execSQL(sql);
b、api提供的面向对象的操作方式:insert()、update()、delete()等
3、如何导入外部数据库:
写一个DBManager类来管理,将数据库文件复制到"/data/data/[package]/databases/"目录下面,然后通过db.openOrCreateDatabase(db文件)打开数据库使用。
2、是否使用过本地广播,和全局广播有什么区别?
本地广播
1、安全性:正在发送的本地广播不会脱离应用程序,不用担心app数据泄露
2、高效:本地广播比全局广播效率高。因为全局广播要维护广播集合表。
3、本地广播不能静态注册。使用LocalBroadcastManager进行注册和反注册
3、是否使用过IntentService,作用是什么
如果有一个任务,可以分成很多个子任务,需要按照顺序来执行,如果需要放到一个service中执行,用IntentService是最好的选择。
因为Service是运行在主线程中的,所以在Service中执行耗时操作会卡住主线程,IntentService可以很好的解决这个问题。
好处:省去了手动开线程的麻烦; 不用手动停止service;由于设计了工作队列,可以启动多次startService(),但只有一个工作队列和一个线程。
4、AIDL解决了什么问题
(Android Interface Definition Language)
由于android系统中进程间无法共享内存,所以需要提供一些机制在不同进程间数据通信。
远程过程调用:RPC-Remote Procedure Call。
android就是提供了一种IDL的解决方案来公开自己的服务接口。AIDL可以理解为双方的一个协议合同。双方都要持有这份协议xxx.aidl文件(android内部编译的时候会将aidl协议翻译成一个xxx.java文件 --- 代理模式:Binder驱动相关,Linux底层通讯相关)。系统源码中大量用到aidl,比如系统服务,启动activity,service
5、Activity、Window、View三者差别,fragment的特点
Activity、Window、View三者协同显示界面。 -- 考察源码熟悉度,View的绘制原理
Activity:剪窗花的人(控制器)
Window: 窗户(承载的一个模型)
View: 窗花(要显示的View)
LayoutInflater: 剪刀
Activity#setContentView(rid) <- getWindow().setContentView(rid) <- PhoneWindow#setContentView(rid) <- (R.id.content)mDecor.addView(view(Rid))
1、Window是一个抽象类,提供了绘制窗口的一组通用API
2、PhoneWindow是Window的具体继承实现类,而且该类内部包含了一个DecorView对象,该DecorView对象是所有窗口(Activity界面)的根View
3、DecorView是PhoneWindow内部类,是FrameLayout的子类,是对Framelayout进行功能的修饰,是所有窗口的根View
Activity.java
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
PhoneWindow.java implments Window
@Override
public void setContentView(int layoutResID) {
// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
// decor, when theme attributes and the like are crystalized. Do not check the feature
// before this happens.
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
// 将layoutResID inflate 到 mContentParent
mLayoutInflater.inflate(layoutResID, mContentParent);
}
...
}
mDecor用来装在包括mContentParent,Actionbar等最外层的view
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor(-1);
...
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
...
}
...
}
根据featureId 预定义主题生成对应的DecorView
protected DecorView generateDecor(int featureId) {
// System process doesn't have application context and in that case we need to directly use
// the context we have. Otherwise we want the application context, so we don't cling to the
// activity.
Context context;
if (mUseDecorContext) {
Context applicationContext = getContext().getApplicationContext();
if (applicationContext == null) {
context = getContext();
} else {
context = new DecorContext(applicationContext, getContext().getResources());
if (mTheme != -1) {
context.setTheme(mTheme);
}
}
} else {
context = getContext();
}
return new DecorView(context, featureId, this, getAttributes());
}
mContentParent 用于存放用户setContentView的View。实例化获取过程
protected ViewGroup generateLayout(DecorView decor) {
...
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
...
return contentParent;
}