1.数据库的操作类型有哪些,如何导入外部数据库?
- 数据 查询(DQL)语言 基本构成 SELECT FROM WHERE
- 数据 操纵(DML)语言 基本构成 INSERT UPDATE DELETE
- 数据 定义(DDL)语言 基本构成 CREATE TABLE VIEW 表的创建 ,属性定义
- 数据 控制 (DCL) 语言 主要时对数据库 进行检测 管理(授权,回滚(SQL>ROLLBACK;),提交数据( COMMIT [WORK])) 数据库本质就是文件,android系统下数据库应该存放在/data/data/com..(package name)/目录下,用到的就是文件流FileInputStream完成文件的复制
if(!(newFile(dbfile).exists())) {
InputStream is =this.context.getResources().openRawResource(R.raw.countries);
//此处raw下的文件为欲导入的数据库,提前保存在工程目录下
FileOutputStream fos =newFileOutputStream(dbfile);
byte[] buffer =newbyte[BUFFER_SIZE];
int count =0;
while((count = is.read(buffer)) >0) {
fos.write(buffer,0, count);
}
fos.close();
is.close();
}
2.是否使用过本地广播,和全局广播有什么差别?
一、本地广播
首先我们要知道,为什么使用本地广播?
本地广播即LocalBroadcastReceiver,仅在自己的应用内发送接收广播,也就是只有自己的应用能收到,数据更加安全广播只在这个程序里,而且效率更高!
引入本地广播的机制主要是为了解决安全性的问题:
1.正在发送的广播不会脱离应用程序,担心app的数据泄露;
2.其他的程序无法发送到自己的应用程序内部,不担心安全漏洞。(比如:如何做一个杀不死的服务---监听火的app 比如微信、友盟、极光的广播,来启动自己。)
3.发送本地广播比发送全局的广播更高效(全局广播要维护的广播集合表效率更低。全局广播,意味着可以跨进程,就需要底层的支持。)
LocalBroadcastReceiver不能静态注册,只能采用动态注册的方式。
LocalBroadcastReceiver使用:
(1)注册
LocalBroadcastManager.getInstance(this).registerReceiver(new XXXBroadCastReceiver(), new IntentFilter(action));
(2) 取消注册:
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)
二:全局广播
BroadcastReceiver是针对应用间、应用与系统间、应用内部进行通信的一种方式
BroadcastReceiver可以静态注册,也可采用动态注册的方式。
BroadcastReceiver 使用:
(1)制作intent(可以携带参数)
(2)使用sendBroadcast()传入intent;
(3)制作广播接收器类继承BroadcastReceiver重写onReceive方法
(4)在java中(动态注册)或者直接在Manifest中注册广播接收器(静态注册)使用registerReceiver()传入接收器和intentFilter
(5)取消注册可以在OnDestroy()函数中,unregisterReceiver()传入接收器
3.是否使用过 IntentService,作用是什么, AIDL 解决了什么问题?
4.Activity、 Window、 View 三者的差别, fragment 的特点?
Activity本身是没办法处理显示什么控件(view)的,是通过PhoneWindow进行显示的
换句话说:activity就是在造PhoneWindow,显示的那些view都交给了PhoneWindow处理显示
1、在Activity创建时调用attach方法:
2、attach方法中会调用PolicyManager.makeNewWindow()
实际工作的是IPolicy接口的makeNewWindow方法
①、其中创建了一个window(可以比喻为一个房子上造了一个窗户):mWindow = PolicyManager.makeNewWindow(this);
②、在window这个类中,才调用了setContentView(),这是最终的调用
在Activity的setContentView方法中,实际上是调用:getWindow().setContentView(view, params);这里的getWindow()就是获取到一个Window对象
Tips:
为啥attch优先于onCreate调用,就是由于在attch方法中,会创建window,有了window才能调用setContentView
3、在IPolicy的实现类中创建了PhoneWindow:
①、由mWindow = PolicyManager.makeNewWindow(this);
②、这里的makeNewWindow(this);方法中,返回的是:return sPolicy.makeNewWindow(context);
③、这个sPolicy实际是一个接口,其实现类是Policy,其中只是创建了一个PhoneWindow
4、在PhoneWindow的setContentView中向ViewGroup(root)中添加了需要显示的内容
①、PhoneWindow是继承Window的
②、setContentView这个方法中,需要先判断一个mContentParent是否为空,因为在默认进来的时候,什么都没创建呢,此时需要创建:installDecor(),DecorView是最根上的显示的
,可以通过adt中的的tools中有个hierarchyviewer.bat的工具,可以查看手机的结构
③、DecorView:是继承与FrameLayout的,作为parent存在,最初显示的
④、下次再加载的时候,mContentParent就不为空了,会将其中的所有的view移除掉,然后在通过布局填充器加载布局
二、三者关系:
1、在Activity中调用attach,创建了一个Window
2、创建的window是其子类PhoneWindow,在attach中创建PhoneWindow
3、在Activity中调用setContentView(R.layout.xxx)
4、其中实际上是调用的getWindow().setContentView()
5、调用PhoneWindow中的setContentView方法
6、创建ParentView:作为ViewGroup的子类,实际是创建的DecorView(作为FramLayout的子类)
7、将指定的R.layout.xxx进行填充
通过布局填充器进行填充【其中的parent指的就是DecorView】
8、调用到ViewGroup
9、调用ViewGroup的removeAllView(),先将所有的view移除掉
10、添加新的view:addView()
Fragment可以作为Activity界面的一部分组成出现;
可以在一个Activity中同时出现多个Fragment,并且一个Fragment也可以在多个Activity中使用;
在Activity运行过程中,可以添加、移除或者替换Fragment;
Fragment可以响应自己的输入事件,并且有自己的生命周期,它们的生命周期会受宿主Activity的生命周期影响。
5.描述一次网络请求的流程
1.通过URL找IP 首先我们的浏览器是不认识baidu.com这个域名的,...
2.对IP结果建立TCP连接 自己主机IP端口的对目标IP的端口(例:http://www...
3.向服务器发送数据 浏览器将网络请求封装成HTTP报文,把HTTP报文通过TCP的分包...
4.服务器解析,并返回 对HTTP报文进行解析,根据HTTP报文决定它请求了什么。将处理的...
5.浏览器解析HTML 浏览器加载显示html的顺序是:从上到下,渲染的顺序也是从上到下...
查看更多步骤...
6.Handler、 Thread 和 HandlerThread 的差别
①Handler:在android中负责发送和处理消息,通过它可以实现其他支线线程与主线程之间的消息通讯。
②Thread:Java进程中执行运算的最小单位,亦即执行处理机调度的基本单位。某一进程中一路单独运行的程序。
③HandlerThread:一个继承自Thread的类HandlerThread,Android中没有对Java中的Thread进行任何封装,而是提供了一个继承自Thread的类HandlerThread类,这个类对Java的Thread做了很多便利的封装。
原文链接
7.低版本 SDK 实现高版本 api
Android给我们提供了两种注解的方式避免编译时报错:
@SuppressLint
@TargetApi
这两种方法又有什么区别呢?
SupressLint很显然的意思是忽略Lint检查,对于我们使用高版本API来说,可以使用@SuppressLint("NewApi")的方式让Lint在编译时忽略所调用API对版本的要求。而@TargetApi是忽略特定版本的API调用报错。
举个栗子:当你的项目minSdkVersion=9,你想使用API 11的新的方法时。此时,使用@TargetApi(11)和@SuppressLint("NewApi")的效果一样,代码都不会报错。但是如果你使用了Api 19才出现的新的方法时,在使用@TargetApi的方法中还是会给你报错,而在另一个方式中依然不会报错。
那这么讲使用@SuppressLint("NewApi")就更好了?
. 正确的使用姿势
当然不是啦!我们要清楚一点,使用上面两种注释的方式只是让lint在编译时不再报错,在低版本的手机系统中,如果直接使用高版本的API肯定会报:“NoSuchMethod”的Crash的。
所以正确的做法应该是在注解的方法中,做版本判断,在低版本中依然使用老的方式处理。版本判断时我们需要判断具体的版本号,比如
1@TargetApi(9)
2public void doSomeThing() {
3 if(Build.VERSION.SDK_INT >= 9) {
4 // 此时我们正常使用API 9的方法,如果这里误使用了Api 11中的方法,编译时就会报错
5 // 提醒我们只是引入API 9中的方法
6 } else {
7 // TODO 使用老的方式
8 }
9}
10
11@SuppressLint("NewApi")
12public void doOthers() {
13 if(Build.VERSION.SDK_INT >= 9) {
14 // 此时我们正常使用API 9的方法,如果这里误使用了Api 11中的方法,编译不会报错
15 // 那么运行在低版本中将会引发Crash的风险
16 } else {
17 // TODO 使用老的方式
18 }
19}