1.Android四大组件
①activity 提供用户界面 用于与用户交互的组件,(活动窗体)它需要为保持各界面的状态,做很多持久化的事情,妥善管理生命周期以及一些跳转逻辑
②content Provider
为应用程序之间访问提供的接口的组件,实现数据共享,结构化数据集合,以表的形式对外提供数据,可以像数据库一样记性选择排序
③BroadCastReceiver (广播)
采用异步机制完成组件之间消息的传递,异步是指广播的发送方将消息标记后发出,不需要得到对方的回应,可以继续做自己的操作
默认情况下,所有的组件都有接收广播的能力,组件想要接收广播就注册与发送方一致的标记
包括普通广播和有序广播:
发送有序广播:sendOrderedBroadCast(...);
sendBroadCast();
有序广播可以进行应用程序之间传递消息,可以根据manifest文件中注册的优先级的高低判断接收的顺序。
实现过程:
创建一个类继承BroadCastReceiver,重写其中的onReceiver()方法,进行接收广播之后的操作。
广播 的生命周期:
④server(服务)
不需要提供用户界面,在后台运行服务于activity,执行长时间耗时操作的组件
开启服务
支付:
导入类库,跳转到支付页面。
短信验证:libs中导入jar包,通过手机号码获取短信验证码,跳转页面子线程睡眠实现倒计时并更新UI,验证码填充判断正确后执行下一步操作。
两个参数:1??.启动源;2??.启动目标
1:这种服务,被称为"开启的"服务.它适合做单一的任务,比如我们可以用它上传或者下载一个比较大的文件.
2:这种服务,不会给调用者返回信息.当某个组件开启这个服务之后,这个组件和该服务之间就没有关系了.
3:也就是说,当开启该服务的组件退出或者销毁后,这个服务仍然会在后台继续执行.
42.怎么实现service
(1)利用绑定activity的方法
步骤1:创建自己的service的方法继承service
onStartCommand()中启动线程
步骤2:在线程中发送广播
步骤3:在Manifest文件中注册service
步骤4:在activity中注册广播
步骤5:开启服务与关闭服务
2.Android中常用的五种布局
①线性布局 LinearLayout:
控件有两种排列方式,垂直和水平布局;android:layout_weight生效,它用于描述该子元素在剩余空间中占有的大小比例,android:layout_weight遵循数值越小,重要度越高的原则。
②相对布局 RelativeLayout:
以某一个元素为参照物来定位的布局方式RelativeLayout是Android五大布局结构中最灵活的一种布局结构,比较适合一些复杂界面的布局。
主要属性: 相对于某一个元素,相对于父元素
③表格布局
适用于N行N列的布局格式。一个TableLayout由许多TableRow组成,一个TableRow就代表TableLayout中的一行。
④绝对布局 AbsoluteLayout:
屏幕左上角为坐标原点(0,0),第一个0代表横坐标,向右移动此值增大,第二个0代表纵坐标,向下移动,此值增大。以android:layout_x和android:layout_y属性来确定控件的位置。在此布局中的子元素可以相互重叠。在实际开发中,通常不采用此布局格式,因为它的界面代码过于刚性,以至于有可能不能很好的适配各种终端。
⑤帧布局 FrameLayout:
所有东西一次都放在左上角,会重叠,适用于一些比较简单的布局
这五种布局元素可以嵌套使用,做出完美的界面
3.handler进制的原理:
答:android提供了handler和looper来满足线程间的通信。Handler先进先出原则。looper用来管理特定线程内对象之间的消息交换(message Exchange).
1)looper:一个线程可以产生一个looper对象,由它来管理此线程里的message queue(消息队列)
2)handler:你可以构造一个handler对象来与looper沟通,以便push新消息到messagequeue里;或者接收looper(从messagequeue里取出)所送来的消息。
3)messagequeue:用来存放线程放入的消息。
4)线程:UI thread 通常就是main thread,而android启动程序时会为它建立一个message queue.
· 事件分发:
· 1. return true:事件会分发给当前 View 并由当前view响应并消费
· 2.return false:事件分发分为两种情况:
如果当前 View 获取的事件直接来自 Activity,则会将事件返回给 Activity响应并消费;
如果当前 View 获取的事件直接来自 父view,则会将事件返回给 父view响应并消费;
3:默认的 :事件会自动的分发给当前 View 的 拦截方法。
事件拦截:
· 1:return True:进行拦截将拦截到的事件交由当前响应并消费;
2:return false,则表示将事件放行,当前 View 上的事件会被传递到子 View 上,再由子View响应并消费;
· 3:return 默认:会被拦截
事件响应::
1:return True:由当前view响应并消费:
2:return False:交由父view响应并消费
3:return 默认:false
侧滑:
1:创建侧滑对象
2:关联布局,设计打开模式
3:设置宽和高
4:把抽屉和activity关联
Handler机制:
Handler要在主线程中创建,创建完之后,这个Handler就会和主线程以及主线程的MessageQueue关联,当通过该Handler在子线程中发送Message的时候,该Message对象就会被发送到主线程的MessageQueue中。当主线程的MessageQueue有一个新的Message对象入队,监视这个MessageQueue的Looper,就会把新入队的Message对象从队列中取出,传递给Handler
国际化
在Android工程的res目录下,通过定义特殊的文件夹名称就可以实现多语言支持。比如我们的程序兼容简体中文、英文,在values文件夹中建立默认strings.xml,再建立values-zh-rCN文件夹。
在每个文件夹里放置一个strings.xml,strings.xml里是各种语言字符串。如果涉及到参数配置类xml文件夹名称也要改成xml-zh、xml。这样在android的系统中进行语言切换,所开发的程序也会跟着切换语言。
4.Android中的动画分类,其特点和区别
(1)属性动画(3.0引入)
根据动画指定的内容,时间等效果实现对当前的view属性设置
(2)控件动画(view)
不会对view当前的属性设置发生改动
①补间动画(Tween)
淡入淡出、旋转、缩放、平移,透明,
②帧动画(Fram)
根据顺序播放排列好的图片
Android的json解析方式:
1:原始方式:new一个JSONObject由得到的object根据json数组名得到json数组,遍历数组得到json对象,根据json对象分别得到各个属性的json字段,再把字段添加到javabin中。
2:fastjson:阿里巴巴开发的json解析方法,先到一个fastjson的jar包到libs中,再根据写好的javabin类用parse方法解析即可。ArrayList<Informationbin2> list = (ArrayList<Informationbin2>) JSON
.parseArray(jsonArray.toString(), Informationbin2.class);
http协议:
工作原理:客户端向服务器发送一条http请求,服务器收到请求后会返回一些数据给客户端,再由客户端对这些数据进行解析。
具体实现方式:
1得到网络请求客户端
HttpClient client = new DefaultHttpClient();
2生成get请求
HttpUriRequest request = new HttpGet(url);
3执行get请求得到一个响应结果
HttpResponse response = client.execute(request);
4判断响应码
if (response.getStatusLine().getStatusCode() == 200) {
5得到一个网络"尸体"--->实体
HttpEntity entity = response.getEntity();
6返回字节数组
return EntityUtils.toByteArray(entity);
5.Android中有哪几种解析XML的类,其特点?
①SAX解析是单向的,不占内存空间,解析属性方便,
缺点:要解析嵌套多个分支来说处理不是很方便
步骤:1:由解析工厂获得解析器
2:由解析工厂解析节点
②DOM解析 官方推荐此解析,它能把XML文件加载到内存里去。可以和
XPath很好的结合,若数据量大,不推荐使用
③Pull解析 用在J2ME对于节点处理比较好,同样节省内存,在J2ME中我们经常使用的KXML库来解析
6.listview的优化方案
①在getView方法中,若convertView为null,则创建convertView并返回,若不为空,则直接使用,在此方法中尽可能少创建view
②给convertView设置tag(setTag()),传入一个viewHolder对象,用于缓存要显示的数据,可打到图像数据异步加载的效果
③如果listview显示的item很多,就要考虑分页加载,规定每页加载多少条,当用户拉到列表底部的时候再去加载接下来的条目
7.Android的数据存储方式
①SharedPreference数据存储
Android提供的用来存储一些简单配置信息的一种机制
需要使用sharedpreferences API读写数据
例如:登录用户的用户名与密码,采用了Map数据结构来存储数据,以键值的方式存储,可以简单的读取与写入,采用XML格式将数据存储到设备中,先调用edit()使其处于编辑窗台,然后修改数据,最后使用commit()提交修改的数据
只能在同一个包内使用,不能在不同的包之间使用
②文件存储
在Android中读取和写入文件的方法对外共享数据
③SQLite数据库存储
④ContentProvider数据存储
继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据,数据访问方式会因数据存储的方式而不同
优点:统一了数据访问方式
⑤网络存储
把数据通过客户端上传至远程服务器
8.activity的启动模式有哪些?什么含义?6天
a、standard 默认的模式。不管被启动的Activity是否存在,都会创建该Activity的对象。
b、singleTop 当被启动的Activity位于栈的栈顶的时候,系统是不会重新的创建该Activity的对象,取而代之的是把创建该Activity对象的Intent对象传入已经存在的该 Activity对象的onNewIntent方法中
c、singleTask 当被创建的Activity栈中不存在,系统会创建该Activity的对象,并且把该Activity存入一个新的Task中
当被创建的Activity已经存在,系统不会重新创建该Activity的对象,取而代之的是把Intent对象传递给该存在的Activity对象的onNewIntent方法
d、singleInstance 和singleTask一样,除了该模式下该Task种只能有该Activity自己,其他的任何Activity都不会在被存入该Task中。
9.activoty的生命周期,5天
Activity的生命周期函数共有7个:
onCreate 当Activity被创建的时候,系统回调该方法。通常在该方法中指定该Activity的界面和初始化界面中的View数据
onStart 表示Activity正在变得可见的一个过程
onResume(重新开始) 表示Activity已经可见了,此时Activity可以接受用户的操作
onPause 表示当前Activity被另一个Activity覆盖,正在变得不可见
onStop 表示当前Activity被另一个Activity完全覆盖,变得不再可见(home键)
onDestroy 表示当前Activity对象被销毁(点返回键)
onRestart 表示某一个完全被覆盖的Activity重新显示
Activity的四种状态:
1、Resumed状态 Activity处于运行态,可以接受用户操作
2、Paused状态 Activity处于暂停态,表示该Activity失去焦点(不能接受用户操作),但是仍然可见(透明)
3、Stoped状态 Activity处于停止态,表示该Activity失去焦点,完全不可见
4、Destroyed状态 Activity处于死亡态,表示该Activity对象被销毁,所占用内存被系统回收
Activity的三种生命周期阶段:
1、entire lifetime(完整生命周期) 从onCreate一直执行到onDestroy
2、visible lifetime(可见生命周期) 从onStart执行到onStop
3、foreground lifetime(前台生命周期) 从onResume执行到onPause
Activity的生命周期的执行顺序
启动的时候 onCreate -> onStart -> onResume
点返回键时 onPause -> onStop -> onDestroy
点home键的时候 onPause -> onStop
点home键之后,重新打开程序 onRestart -> onStart -> onResume
当启动一个透明的Activity或者一个没有覆盖完屏幕的Activity的时候 第一个Activity的生命周期执行 直接onPause 销毁该透明的Activity第一个Activity的生命周期执行onResume
10 activity在屏幕旋转时的生命周期
如:在2.2的版本系统上
由竖屏切换到横屏 Activity会被销毁一次重建一次
由横屏切换回竖屏 Activity会被销毁多次重建多次
Activity配置信息发生变化时对Activity生命周期的影响
默认情况下当配置信息(屏幕方向、键盘的可用与否...)发生变化的时候,系统会销毁原始配置信息下的Activity对象,然后在新的配置信息下重新创建该Activity以适应新的配置环境(方向)
通常情况下当手机的方向(配置信息)发生变化的时候,不希望当前的Activity被销毁的,可通过
android:configChanges="orientation|keyboardHidden" 指定由Activity自己处理配置信息的变化,属性的值指明了Activity能够处理的配置信息的类型
Activity自行处理配置信息发生变化的方式:需要在Activity在重写onConfigurationChanged方法,在此方法中接收新的配置信息,根据配置信息做一些响应的处理
11.注册广播有几种方式?这些方式的优缺点;谈谈Android引入广播机制的用意
①动态注册 在代码中注册
IntentFilter intentFilter = new IntentFilter(..action..)
IncomingSMSReceiver receiver = new IncomgSMSReceiver();
registerReceiver(recerver,filter);
②静态注册 在清单文件中注册
<receive android:name="包名.类名 " >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED")//必须有action,此action可以任意命名。
<intent-filter>
<receiver>
MainActivity里
Intent intent=new Intent();
intent.setAction("1421");
存储信息intent.putExtra("info", "我是activity");
发送一个广播消息
sendBroadcast(intent);
MyReceiver extends BroadcastReceiver里
if("1421".equals(action)){
获取intent中存储的消息
String info = intent.getStringExtra("info");
Toast.makeText(context, "收到广播了...消息="+info, Toast.LENGTH_LONG).show();
1、普通广播(无序广播)
通过sendBroadcast方法所发送的广播,被称为无序广播。
无序广播的接收是异步的(所有能接收该类型的广播的接收器能够同时接收该广播,而不用互相
等待)
接收无序广播的接收器不能调用result和abort方法
2、有序广播
通过sendOrderedBroadcast方法所发送的广播,被称为有序广播。
有序广播的接收是同步(在同一时刻,只有一个接收器能够接受该广播,所有的接收器是按照先
后顺序依次接收广播)
可以通过android:priority(优先级)属性控制广播的接收顺序
优先级低的广播可以被优先级高的终止(可以调用result和abort方法)
终止广播:abortBroadcast();
传递:setResultExtras(bundle);
android:priority属性可以同时控制(有序广播)和(无序广播)的接收顺序 }
.动态注册和静态注册的区别:
1
//动态注册:在程序退出后,该广播接收器不能收到新的广播;
//静态注册:在程序退出后后,该广播接收器还可以继续接收到新的广播.
2动态注册更常用一些;静态注册用的相对少一些;
3一般情况下,动态注册适用于接收自定义的广播;静态注册适用于接收系统广播;
4动态注册是在Activity中通过registerReceiver()方法来注册,通过unRegisterReceiver()取消注册;
//静态注册直接在清单文件中通过<receiver>节点注册就可以了,不用取消注册.
动态广播:
//注册广播接收器
//两个参数:1??.要注册的广播接收器;2??.IntentFilter意图过滤器.
receiver = new DynamicReceiver();
//意图过滤器
IntentFilter filter=new IntentFilter();
//添加action属性.
filter.addAction("dynamic");
filter.setPriority(100);
//注册广播接收器
registerReceiver(receiver, filter);
12.适配器控件
必须有数据源,然后交给适配器控件,适配器显示到控件中
spinner AutoCompleteTextView listView viewPager
纯文本 ArrayAdapter
有文本有内容有图片 SimpleAdapter
数据库中的数据源用 CursorAdapter SimpleCursorAdapter
滑动功能 pagerAdapter fragmentpagerAdapter
13.activity的传值方式,传的数据必须是可序列化数据
序列化:用于作为一种将 Java 对象的状态转换为字节数组,以便存储或传输的机制,以后,仍可以将字节数组转换回 Java 对象原有的状态。
实际上,序列化的思想是 “冻结” 对象状态,传输对象状态(写到磁盘、通过网络传输等等),然后 “解冻” 状态,重新获得可用的 Java 对象。所有这些事情的发生有点像是魔术,这要归功于 ObjectInputStream/ObjectOutputStream 类、完全保真的元数据
①直接传值intent
Intent intent = new Intent(...);
intent.putExtra("","");
startActivity(intent);
目标 getIntent()
Intent intent = getIntent();
intent.getStringExtra("...");
②Bundle对象
Intent intent = new Intent(...);
创建bundle对象
Bundle bundle = new Bundle();
bundle.putString(...);
intent.putExtras(bundle);
startActivity(intent);
目标Activity
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
int in = bundle.getInt("...");
③回传
启动时
startActivityForresult(intent,REQUEST_CODE);
回传通过setResult
//通过隐式Intent启动浏览器
<activity>
<intent-filter>
<action android:name="...."/>
<category android:name="android.intent.category.DEFAULT"/> <!--此句一般都要加 -->
</intent-filter>
</activity>
当action和category同时满足才行
Intent intent = new Intent();
//给Intent的action属性赋值(Intent.ACTION_VIEW指明该Intent的操作是浏览)
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
重写onActivityResult()方法
④application方法
⑤通过剪切板传值
将内容先存在剪切板中,再从剪切板中粘贴
Intent的七大属性:
ComponentName,Action,Category,Data,Type,Extra,Flag
14.回退栈,先进后出
15.什么是ANR,如何避免它?
Application Not Responding 应用程序无响应,它是由活动管理器和窗口管理器共同监管的,若在用户操作5s内应用程序没有做出响应,BroadCastReceiver在10s内没有执行完毕,则会出现应用程序无响应强行关闭。
避免:
尽量在关键方法onCreate或onResume方法中少的创建操作,将高耗时的操作交给子线程来处理
16.线程是如何停止的?
1.run方法执行完,自然停止
2.设置一个标示flag,当flag=false 时停止线程
3.用interrupt强制停止
17.简要解释activity,intent,intent filter,service,Broadcase
BroadCastReceiver
activity是一个可视化界面,可以与用户进行交互操作,
service没有可视化界面,在后台进行长时间耗时操作的组件
intent是一个对象,他可以显式的指定目标activity,然后进行跳转操作
当目标activity找不到是隐式的,则通过intent filter 告诉目标activity能处理的intent,它是在Intent filter中声明的
Broadcast是采用一种异步机制对外发送广播,发送方将消息标记后发出,不用等待对方回应就可以继续进行操作
BroadcastReceiver 是接收广播的消息,需要注册与发送方一样的标记才可以接收到
18,MVC模式的原理
model,view,controller
模型对象
所有的业务逻辑都写在该层
视图对象
负责生成用户界面的部分,接收用户的输入,显示处理结果
唯一可以让用户看见的一层
控制层
根据用户的输入,控制用户界面数据显示及model对象状态的部分
19.Android的系统框架
linux内核层
负责硬件的驱动,内存的管理
运行环境 运行环境负责解释和执行生成的da和本地类库
lvik格式的字节码,本地类库中存放了很多关于android的代码类,它是开源的函数库
应用程序框架层
开发人员运用本层封装好的API来进行开发
应用程序层
开发人员开发程序层可以调用内置的应用程序
下层为上层服务,稳定性,灵活性和可扩展性
20.contentProvider如何实现数据共享
继承contentProvider抽象接口,存储和检索数据,重写其中的方法,就可以实现以数据库表的形式对外暴露数据,如果想要应用程序的数据公开化,有两种方法:
创建一个属于自己的contentProvider或将数据添加到已有的contentProvider中,有相同的数据类型并且contentProvider的权限
外界程序可以通过contentSolver接口访问contentProvider提供的数据
21,IntentService优点
当处理intent时会产生一个对应的service,android的进程处理器会尽可能的不kill掉你
22、 如果后台的Activity由于某原因被系统回收了,如何在被系统回收之前保存当前状态?
在activity在回收之前调用onStateInstanceState()方法,在此方法中保存需要保存的数据,通过重写onRestoreInstanceState()方法从中提取保存的数据
23.设置窗口样式
android:Theme = "@android:style/Theme.Dialog"
设置透明度
android:Theme = "@android:style/Theme.Translucent"
24.一条最长的短信中文占(包括标点)70个字节
英文占160个字节
25.如何退出activity?如何安全退出多个activity?
(1)对于单一的activity来说,想要退出就直接用finish()方法退出,或者也可以用killProcess()和System.exit()方法
(2)对于多个activity,
①每打开一个activity,就记录下来,在需要退出的时候关闭每一个activity即可
②发送特定广播:在需要退出activity时就发送一个特定的广播,当activity接收到广播后关闭即可
③递归退出:在打开新的activity时使用startActivityForResult()方法,然后自己加标志,在onActivityResult中处理,递归关闭
④抛出异常:在需要退出的时候抛出异常使其ForceClose(),问题是如何使程序结束掉,不弹出ForceClose的窗口
26.AIDL全称?如何工作?能处理那些类型的数据?
用来实现进程间的传递
Android Interface Define Language 接口描述语言 基于接口轻量级的
②不需要import声明的简单java编程语言类型
String CharSequence不需要特殊声明
List Map。这些所包含的成员必须是简单的数据类型
③编译器通过aidl文件生成一段代码,通过预先定义的接口达到进程内部之间通信的目的。若需要在activity中需要访问另一个service里的对象,需要先将对象转化成AIDL可识别的参数,然后用AIDL来传递这些参数,在消息的接收端,使用这些参数来组装成自己需要的对象
编译器通过aidl文件生成一段代码,通过预先定义的接口实现进程内部之间的同行。若一个activity中需要调用另一个service中的某个参数,则可以先把参数转化成aidl可识别的参数,然后通过aidl传递参数,在消息接收端,需要将参数组装成自己的对象
27.运行时权限Dalvik(Android授权)
文件系统权限linux内核授权
28.直接发送Uri把参数带进去,或在manifest文件中的intentfilter中的data属性
29.android系统的优势和不足
30、Android dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念
DVM 是Dalvik虚拟机
每个Android应用程序都在它自己的进程中运行,都需要拥有一个Dalvik虚拟机实例,每个DVM都在linux中的一个进程,可以认为是同一个概念
31. sim卡的EF文件是什么?有何作用
sim本身有自己的操作系统
EF就是做存储和手机通讯用的
32.嵌入式内存管理有哪几种形式
页式 段式 段页 MMU 虚拟空间等技术
33.嵌入式实时操作系统
Android是基于linux内核的,是属于软实
嵌入式实时操作系统是指当外界产生数据时能够以足够快的速度接收并处理数据,处理的结果在规定的时间之内来控制生产过程和对处理数据做出快速相应,并控制所有实时任务协调一致运行 实时系统分为软实和硬实两种
嵌入式实时操作是指当外界产生数据时能以足够快的速度接收并处理数据
,将处理的数据在规定时间之内对数据做出快速响应,并控制实时任务协调一致运行
34.如何将SQLite数据库与apk文件一起发布?
可以将dictionary.db文件复制到res文件夹下的aw中,在此目录下文件不会被压缩,还可以直接提取该目录中的文件
35.如何打开res aw目录下的数据库文件
在Android中不能直接打开res aw目录中的数据库文件,而当程序在第一次启动时将该文件复制到手机内存或SD卡的某个目录中,然后读取该数据库文件,复制的基本方法使用getResources().openRawResource
SOLiteDatabase.openOrCreateDatabase方法来打开任意目录中的SQLite数据库文件
36.DDMS是程序执行查看器
RraceView是程序性能分析器
JNI接口 java native interface java 本地接口
37.IPC(进程间通信)机制
IPC是内部进程通信的简称,是为了实现activity和service之间可以随时进行交互,通过定义AIDL接口文件来定义IPC 接口,Service端实现IPC 接口,Client端调用IPC接口本地代理。
38.NDK是一些工具的集合
39.应用怎么优化?
(1)代码优化:尽量使用继承,实现高内聚低耦合
(2)布局优化:尽量少嵌套布局,使用include引用
(3)性能优化:图片要加缓存+裁剪,listview在滑动停止后要进行加载
40.多线程的理解?
(1)使用原因:主线程不能更新UI,主线程做耗时操作可能导致UI线程阻塞,给用户带来不便
(2)使用方式:Handler,Thread,AsyncTask,HandlerThread,Timer定时器
(3)Handler + Thread:sendMessage来发送消息,由what表示发送标识,obj表示代入数据
41.多线程同步的方式有哪些(同步就是一个线程执行完了才能执行另一个线程)
①Synchronized同步锁:锁代码块和锁方法
②利用Hander,在每个线程中都设有Hander的实例对象,利用sendMessage()互相发送来达到同步
43.seekBar拖动条
通过seekBar.getProgress()获取seekBar的值
SeekBar.OnSeekBarChangeListener()处理拖动条值的变化
Menu菜单
44.IoC控制反转
activity下面的方法是框架调用的,系统自动调用onCreate不是程序编写者主动去调用,反而是用户写的嗲吗被框架调用,也就是反转。例如数据库的管理类
45.数据库的基本操作
①第一步,创建一个类继承SQLiteOpenHelper
②第二步,实现SQLiteOpenHelper中的两个方法(创建数据库方法和数据库版本升级的方法)
③第三步,使用SQLiteOpenHelper的实例获得SQLiteDatabase的实例
④第四步,获得SQLiteDatabase的实例就可以实现增删改查的操作
getReadableDatabase是以读写的方式打开数据库,如果磁盘控件已满,则不会抛出异常,以读的方式打开数据库
getWritableDatabase是以写的方式打开数据库,如果磁盘控件已满,则会抛出异常
46.get/post请求的区别
一个MVC的面试题
Android中界面部分也采用了当前比较流行的MVC框架,在Android中:
1) 视图层(View):一般采用XML文件进行界面的描述,使用的时候可以非常方便的引入。当然,如何你对Android了解的比较的多了话,就一定可以想到在Android中也可以使用JavaScript+HTML等的方式作为View层,当然这里需要进行Java和JavaScript之间的通信,幸运的是,Android提供了它们之间非常方便的通信实现。
2) 控制层(Controller):Android的控制层的重任通常落在了众多的Acitvity的肩上,这句话也就暗含了不要在Acitivity中写代码,要通过Activity交割Model业务逻辑层处理,这样做的另外一个原因是Android中的Acitivity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。
3) 模型层(Model):对数据库的操作、对网络等的操作都应该在Model里面处理,当然对业务计算等操作也是必须放在的该层的。就是应用程序中二进制的数据。
图片缓存的三种方式:
1.lrucache 强引用 内存缓存
SoftReference<Bitmap> 软引用
2.磁盘缓存 sd卡缓存 保存到本地
3.网络缓存
先在内存中找,如果没有则在磁盘中找存到内存,若都没有就在网络中找
51.imageloader图片错位的原因,怎么下载的流程图
原因:convertView的复用,比如说listView滑到第二行异步加载某个图片加载很慢,在加载过程中
listView已经滑倒第14行,其第二行的加载已经结束,第二行已不在屏幕内,第二行的数据可能被第14行复用,这是之前的图片加载结束,就会显示在第14行,造成错乱。
下载的流程图:
先在内存中找,如果没有则在磁盘中找存到内存,若都没有就在网络中找
下载下来之后,先存如磁盘,再存入内存。
52.
53.异步任务
进行长时间耗时操作的,其有三种泛型:
params,Progress,Result
四个步骤:
异步.excute()方法启动异步任务
①onPreExcute()
异步任务执行操作前做一些准备工作。
②doInBackground()
子线程中的耗时操作,可调用publishProgress方法来更新实时的任务进度。
③onProgressUpdate()
用publishprogress方法启动此方法
④onPostExcute()
传递线程执行的结果。
54.数据库操作
SQLiteDatabase db = helper.getWritableDatabase();
以读写方法打开数据库,若数据存储已满,则只以读的方式打开数据库,用此方法就会出错
SQLiteDatabase da = helper.getReadableDatabase();
以上两种方法可以得到SQLiteDatabase的实例,
db.openDatabase();
增,删,改,查
创建数据库:
String sql = “Create table user(id Integer primary key,name vachar(30))”
db.execuSQL(sql);
增:
55.同时下载500张图片,怎么实现“?
可以采用线程池。比如有500个线程,但同时执行的只有5个线程,其他线程处于等待状态,当执行完一个线程后后边接着有一条线程开始执行。
项目难点:
1.Android的事件处理机制和屏幕适配
A、使用wrap-content和match-parent(api2.2之前使用fill-parent),即宽高根据内容调整以及伸展至父控件一致。而不是硬编码写死控件的大小。
B、使用相对布局(RelativeLayout)
使用相对的布局方式来进行控件的摆放,这种方式灵活性大,但是也相对复杂。
C、使用FrameLayout,即帧布局可以在一定程度上消除屏幕尺寸带来的问题。
D、使用layout-xlarge,layout-large,layout-small这种方式来建立多个布局文件。使用这种方式可以仅用四个布局文件就匹配所有高于1.6版本的应用。并且效果比只用一个layout要好很多。
E、一些重要的图片,比如logo,主页面的那些图片可以使用9.png图片,因为这种图片拉伸后不会出现很严重的失真,所以显示效果会相比于普通的png图片要好。
F。res中使用drawable-hdpi,drawable-mdpi这种方式来定义不同的图片,可以帮助我们适应不同的屏幕密度。
2.百度地图
(1)申请密钥(名字为应用程序包名)
(2)在manifest文件中的application下
<!--配置地图开发的密钥 key 需要自行申请-->
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="kBfIIOi9jm3xGdW5O0LcrXDM"
/>
(3)添加百度地图开发所需要的权限
(4)xml文件中添加表示展示地图的控件MapView
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
(5)展示基本地图大概思路
private MapView mapView ;//声明地图控件
private BaiduMap baiduMap;//声明地图的控制对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//在使用SDK各组件之前初始化context信息,出入ApplicationContext
//注意该方法要在setContentView方法之前实现
setContentView(R.layout.activity_map);
//获取地图显示控件对象
mapView = (MapView) findViewById(R.id.bmapView);
baiduMap = mapView.getMap();//获取地图控制器
baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);//默认普通的地图
// baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);//卫星的地图
baiduMap.setTrafficEnabled(true);//表示展示当前的交通状态
}
检查密钥的方法
onCheckKey(){///...}
当Activity处于生命周期的任何状态时,mapview也随之处于该状态
(6)添加覆盖物的方法
除了创建上述的baiduMap控制对象,接下来第一步需要通过BitmapDescriptorFactory创建BitmapDescriptor对象
第二步创建标记点的位置Latlny
第三步创建图层对象OverlayOptions
第四步就将图层对象添加到地图上使用方法addOverlay();
绑定地图标记的单击事件表示当地图标记被单击时回调的方法
baiduMap.setOnMarkerClickListener(new OnMarkerClickListener(){
public boolean onMarkerClick(){
}
});
第五步点击出现弹窗,InfoWindow对象
(7)POI检索步骤
接以上4步
第五步绑定poi检索获取结果监听器
poiSearch.onGetPoiSearchResultListener(...){..
有两个方法:
onGetPoiResult(...){...}
onGetPoiDetailResult(...){...}
.}
第六步创建类继承PoiOverlay的覆盖物,通过重写里面的两个方法
①构造器
②onPoiClick()确定poi检索的所有集合
(8)定位步骤
定位有三种模式:
高精度定位模式:使用网络定位和GPS定位
低功耗定位模式:使用网络定位
仅用设备定位模式:不需要衔接网络的情况下进行定位,不支持室内环境的定位
①创建位置接收器对象locationClient(位置接收器必须在主线程中声明)
②设置当前定位的地图使用的坐标系 locationClientOption.setCoorType("");
③位置接收器注册注册接收位置的监听
registerLocationListener(...){
接收到定位信息时回调该方法
onReceiveLocation(...)
}
(9)路线规划
通过单例模式获得路线规划查询器
主要通过routePlanSearch.setOnGetRoutePlanResultListener(...){
步行路线
onGetWalkingRouteResult(...)
公交路线
onGetTransitRouteResult(...)
驾车路线
onGetDrivingRouteResult(...)
}
创建一个类继承DrivingRouteOverlay
其中有点击路线规划中的node节点触发事件(onRouteNodeClick(...))
位置接收器对象启动
locationClient.start();
发送位置请求
locationClient.requestLocation();
3.极光推送
4.反射注解的应用
①反射注解是为了减少findviewbyid
②如果需要用到一个系统类中的属性和方法,可是又不知道这个类中有什么属性和方法,可以通过反射获得这个类中的属性和方法,通过setAccessiable方法将他设为public,然后通过set方法进行赋值
5.实现新浪和腾讯微博获得授权登录、分享等功能
使用第三方ShareSDK操作
第三方登录前需要准备两项工作
①开放API
②实现第三方的授权
其第三方登录分为两种:
①要功能,不要数据
当触发第三方登录事件时,获取用户的ID,将用户的id与服务器平台中的内容相比较,若存在,则为合法用户,允许进入系统;否则调用authorize()方法将引导用户进入授权页面,输入账户名和密码。若调用了onComplete()方法,则授权成功,否则调用removeAccount()方法清除第三方登录的缓存数据。
②要数据,不要功能
当触发第三方登录事件时,获取用户的资料,进行授权操作,若调用onComplete()方法,则说明授权成功,引导用户直接进入登录(login)页面,否则提示错误。调用removeAccount()方法清理授权缓存数据。登录时客户端发送用户资料的id给服务端,服务端判定用户是否已经注册用户,若已注册,则引导用户进入系统,若没有注册,则进入注册页面,注册时用户挑选自己注册的所需字段,并提交给服务端,服务端完成注册后反馈给客户端引导用户进入系统。否则调用removeAccount()方法,删除可能的授权缓存数据。
6.二维码的功能实现(********)
7..SlidingMenu的实现
slidingMenu也是一种控件,实例化控件的三种方式:
(1)继承slidingMenu自带的slidingMenuFragmentActivity
(2)SlidingMenu menu = new SlidingMenu(context);
(3)xml文件注册
8.检查更新操作的实现、
1.检测当前版本的信息AndroidManifest.xml-->manifest-->android:versionName。
2.从服务器获取版本号(版本号存在于xml文件中)并与当前检测到的版本进行匹配,如果不匹配,提示用户进行升级,如果匹配则进入程序主界面。
3.当提示用户进行版本升级时,如果用户点击了确定,系统将自动从服务器上下载并进行自动升级,如果点击取消将进入程序主界面。
9.BitmapFactory.Options进行图片的二次采样(****************)
为了防止加载大图片造成内存溢出
方法一
计算 图片 的原始宽高,默认缩放为1,
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; 仅仅解码边缘区域
//如果指定了inJustDecodeBounds,decodeByteArray将返回为空
BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);
//得到宽和高
height = options.outHeight;
width = options.outWidth;
//图片实际的宽与高,根据默认最大
while((height / sampleSize > Cache.IMAGE_MAX_HEIGHT) ||
(width / sampleSize > Cache.IMAGE_MAX_WIDTH)){
sampleSize *= 2;
}
//不再只加载图片实际边缘
options.inJustDecodeBounds = false;:
//制定缩放比例
options.inSampleSize = sampleSize;
return BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);
方法二:
通过原始图片的 宽高和现在图片的宽高计算出缩放的比例,然后再通过缩放的比例缩放。
//给定的BitmapFactory设置解码的参数
BitmapFactory.Options options = new BitmapFactory.Options();
//从解码器中获取原始图片的宽高,这样避免了直接申请内存空间
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(...);
options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
//压缩后便可以将其设置为false了
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(...);
。。。
10.每个item的动画缩放的实现
从xml文件中设置,然后引用布局
11.AudioManager实现对手机情景模式的控制
12.可扩展的listview
Android 编程下 Touch 事件的分发和消费机制
1事件的分发
true:由当前view响应并消费
false:一:事件来自activity则返回activity响应并消费;
二:事件来自父view则返回父view响应并消费;
默认:给当前view的拦截事件
2:事件拦截:
true:由当前view响应并消费
false:交由子view响应并消费
默认:同ture
3:事件响应:
true:当前view消费
false:交由父view响应并消费
默认:同false
第三方登陆:
1:首先你需要选择一个第三方平台
2、用户触发第三方登录事件 调用platform.getDb().getUserId()请求用户在此平台上的ID
3、如果用户ID存在,则认为用户是合法用户,允许进入系统;否则调用authorize()
4、authorize()方法将引导用户在授权页面输入帐号密码,然后目标平台将验证此用户
5、如果onComplete()方法被回调,表示授权成功,引导用户进入系统
6、否则提示错误,调用removeAccount()方法,
一.是一种可以扩展的listview,就是那种点击一下可以扩展出子项,再点一下收缩回去的显示list。因为需要查看一堆文件的目录结构,就使用了expandablelist以便于直观地看到结构形式。
一、ExpandableListView
一个垂直滚动的显示两个级别(Child,Group)列表项的视图,列表项来自ExpandableListAdapter 。组可以单独展开。
其所用到的重要方法如下:
1. expandGroup(int groupPos) :在分组列表视图中展开一组,
2. setSelectedGroup(int groupPosition) :设置选择指定的组。
3. setSelectedChild(int groupPosition, int childPosition, boolean shouldExpandGroup) :设置选择指定的子项。
4. getPackedPositionGroup(long packedPosition) :返回所选择的组
5. getPackedPositionForChild(int groupPosition, int childPosition) :返回所选择的子项
6. getPackedPositionType(long packedPosition) :返回所选择项的类型(Child,Group)
7. isGroupExpanded(int groupPosition) :判断此组是否展开
二、ExpandableListAdapter
一个接口,将基础数据链接到一个ExpandableListView。此接口的实施将提供访问Child的数据(由组分类),并实例化的Child和Group。
其里面重要方法:
1. getChildId(int groupPosition, int childPosition) 获取与在给定组给予孩子相关的数据。
2.getChildrenCount(int groupPosition) 返回在指定Group的Child数目。
3.getChildView() 获取子视图(就是二级视图)
4. getChildView()获取父视图
13.通知
左边的popWindow
*/
popView_left = getLayoutInflater().inflate(
R.layout.nearby_popwindow_left, null);
popupWindow_left = new PopupWindow(popView_left, displayMetrics.widthPixels,
LayoutParams.WRAP_CONTENT, true);
// 以下三句设置点击空白处时popwindow会消失
popupWindow_left.setTouchable(true);
popupWindow_left.setOutsideTouchable(true);
popupWindow_left.setBackgroundDrawable(new BitmapDrawable(
java中也是4个字节 getResources(), (Bitmap) null));