1.Int a =1;
Int result = a+++3<2;
Result = 16
其中<<是左位运算 num<<1相当于乘以2
>>是右位运算 num>>1 相当于num除以2
2.写出两种单列模式
饿汉式
class Single{
Private Single(){}
Private static Single s = new Single();
Public static Single getInstance(){
Return s;
}}
懒汉式
Class Single2{
Private Single2()
Private static Single2 s = null;
Public static Single2 getInstance(){
If(s==null)
S = new Single2();
Return s;}}
Activity的生命周期
onCreate() 在这里创建界面,做一些数据的初始化工作
onStart() 变成用户可见,不可交互的状态
onResume()变成和用户可以交互的状态
onPause()是可见的,但是不可以交互的
onStop()变得不可见,被下一个Activity覆盖
onDestory()
Back键 onPause()onStop()onDestory()
Home键onPause()onStop(),再次启动onRestary()onStart()onResume()
BroadcastReceiver的生命周期
Broadcastreceiver生命周期中有一个回调方法onReceiver(Context context,Intent boardcast)当接收器收到一条broadcast消息,Android就会调用onReceiver,并创递给它一个Intent对象,这个对象携带着那条broadcast消息,我们认为仅当执行这个方法的时候,BroadcastReceiver是活动的,这个方法返回时,它就终止了。这就是BroadcastReceiver的生命周期
由于BroadcastReceiver的生命周期很短,一个带有活动的BroadcastReceiver的进程时受保护的,以免被干掉,但是Android会在任意适合干到那些携带不在活动的剪裁,解决上述方案,采用一个Service来完成这项工作,Android会认为哪个进程中仍然有活动的组件,生命周期只有10s面左右,如果在onReceiver内做超过10s的事,就会报ANR。
在配置文件中声明broadcast Receiver几乎总是需要intent filter在配置文件中完成声明后,及时应用当前未运行,只要有匹配的broadcast intent的发来,broadcast Receiver就会接收,一收到intent,broadcast receiver的onReceiver方法开始运行,然后broadcast receiver就会被销毁。
注册和接收BroadCastReceiver两种方式的区别:
两种方式分别是在程序中动态注册和在xml中指定,区别就是范围不同,程序中动态注册的接收者只能在程序运行过程中有效,而在xml注册的接收者不管你的程序有没有启动都会起作用
写出几种Service和Activity的交互方式
共有3种交互方式:
1.广播交互:
通过广播的方式实现Activity和Service的交互操作,简单而且容易实现,可以胜任简单级的应用,但是缺点也十分明显,发送广播受到系统制约系统会优先发送系统级的广播,造成我们自定义的广播功能会延迟,同时广播接收器中不能处理长时间耗时的操作,否则就会ANR
2.共享文件交互:
这里提到的共享文件是指,Activity和Service使用同一个文件来达到传递数据的目的,使用sp来实现共享,也可以使用IO。但是实现交互的时候需要注意,对于文件的读写,同一时间只能一方读,一方写,不能两方同时写,当写入数据较为复杂或者数据量比较大的时候,就有可能导致写入和读取的数据不一致的错误。
3.Message交互
引用一个Handler对象和平时使用Handler和Thread通信的方式相同
UI线程和非UI线程的交互方式
不要在UI线程里面写写耗时的操作,导致UI线程堵塞
不在在UI线程里面绘图
交互方式有:
Handler;Activity.runonthread;view.post(Runnable);view.postDelayed(Runnable);AsnyTask
requestLayout,invalidate和postInvalidate的异同
Android中显现View的更新有俩种方法,一种是invalidate另一种是postInvalidate其中,前者是在UI线程自身中使用,而后者是在非UI线程中使用。
使用invalidate刷新,需要配合Handler使用,使用异步非UI线程转到UI线程中调用,如果要在非UI线程中直接使用,就会用postInvalidate方法,省去使用Handler
requestLayout使用,当View确定自身已经不再适合现有这个区域时,给View本身调用这个方法,要求parentview(父类的视图)重新调用它的onMeasure onLayout来重新设置自己的位置,特别是当View的Layoutparameter发生改变,并且它的值还没能应用到View上时,适合调用这个方法
http怎么加入超时和代理
http链接的超时机制能够方式联系线程的无限等待
HttpClient httpclient = new DefaultHttpClient();
HttpParams patams = htttpClient.getParams();
HttpConectionParams.setConnectionTimeOut(params,HTTP_CONNECT_TIMEOUT);
HttpConnectionParams.setSoTimeou(params.HTTP_SOCKET_TIMEOUT);
HttpURLConnection
Try{
URL url = new URL(“www.baidu.com”);
HttpURLConnection coon = (HTTPURLConnection)url.openConnection();
coon.setConnectionTimeout(HTTP_SOCKET_TIMEOUT);
}
Catch(Exception e)
e.printException}
设置代理
Httpclient httpclient = new DefaultHttpClient();
String host = Proxy.getDefaultHost();
Int port = android.net.Proxy.getDeaultPort();
SocketAddress sockAddr = new InetSockAddress(host,port);
java.net.Proxy proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP,sockAddr);
Try{
URL url = new URL(“www.baidu.com”);
HttpURLConnection conn = (HttpUrlConnection)url.openConnection(proxy);
Catch(Excepiton e){
e.printStackTrace()}}
Sleep,wait,notify的区别
Sleep是线程类的方法,是Thread的静态方法,需要传参数,导致线程暂停指定的时间,给执行其他线程,但是监控状态依然会保持,到时候会自动恢复,调用sleep不会释放对象锁。
Wait是Obeject类的方法,可以不用传参数,对此对象调用wait方法导致此对象放弃对象锁,进入等待此对象的等待锁定池,只有对此对象发出notify方法治好,本线程才进入对象锁定池,准备获得对象锁进入运行状态。在其他线程调用此对象的notify()方法或者notifyAll()方法前,导致当前线程等待
View和viewGroup的关系
View是所有UI组件的基类,而ViewGroup是容纳这些组件的容器,也是View的子类
如何定位和解决Android的内存溢出问题
当项目中包含大量的图片,或者图片过大的时候会导致oom,等比例缩小,对图片进行软引用,及时进行recycle操作
对复杂的listview进行合理的设计和编码
单个页面,横竖屏切换N次会导致OOM,在代码中引用,并在onDestory时候及时释放,避免xml的重复加载
简述Observer设计模式,并且画出Oberver模式的典型结构类图
定义了一种一对多的依赖光纤,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态上发生变化,会通知所有观察者对象,自己更新自己
&&和&的区别
这两个都是逻辑运算符,判断两边为真则语句成立,但是&&是第一个条件不成立之后,后面的都不执行了,但是&则是要继续执行。
静态成员类,非静态成员类有什么区别?什么是匿名内部类?
静态成员类就是该类的所有对象可以共享,非静态成员类是普通成员
匿名内部类就是没有名字的内部类,因为没有名字,所有匿名内部类只能使用一次,用来简化代码
一个有N个元素的一维数组(A[0],A[1], ..., A[n-1]),设计一个算法求解该数组最大子数组
int maxnum = A[0]+A[1]
For(int i =0;i<N;i++){
Int tempnum = A[i-1]+A[i];
If(maxnum<temnum){
Maxnum = temnum;}}
Handler机制原理,内部类是如何实现的,消息队列的实现机制
UI更新只能在UI线程,即主线程,子线程更新UI要用Handler
什么是ANR,如何定位和避免
Anr application not responding 在Android中,活动管理器和窗口管理器这两个系统负责监视应用程序的相应出现对输入事件(按键,触屏事件)响应超过5s,意向接收器超过10s仍然有未完成执行,在主线程中有大量耗时操作。
简述Android的启动过程
Init进程启动 Native服务启动 System Service Android服务启动 Home启动
线程的同步
有可能线程间相互干涉和内存一致性的问题,采用synchronized关键字
getHeight和getMeasureHeight的区别
getMeasureHeight是在Measue()过程结束之后就可以获取到的,而getHeight方法要在onLayout之后才能获取
根据源码,getwidth返回的是右边坐标减去左边坐标,这里需要布局之后才能确定它们的坐标,也就是说在布局之后调用getwidth方法,所以getwidth获得的宽度是View在设定好布局之后的整个View的宽度。
getMeasureWidth:
得到的是最近一次调用measure()方法测量后得到的是View的宽度,它应该仅仅用在测量和Layout的计算getMeasuredWidth()是对View上的内容进行测量后得到的View内容占据的宽度。 前提是你必须在父布局的onLayout()方法或者此View的onDraw()方法里调用measure(0,0);(measure中的参数的值你自己可以定义),否则你得到的结果和getWidth()得到的结果是一样的。
如何实现View判断单击和双击?自定义view的OnDraw方法主要做什么
实现OnTouchListener复写onTouch方法,如果两次间隔小于300ms,则为两次点击
onDraw()ViewRoot中的代码会继续执行,并创建一个Cancas对象,然后在调用View的draw()方法,来进行绘制
在绘制过程中,先得到一个mBGDrawable对象,来根据layout过程确定的视图位置来设置背景的绘制区域,之后调用Drawable的draw()方法来完成背景的绘制工作,在onDraw()的方法里传入Canvas这个类
图片的缓存机制,如何做到高效和稳定
获取图片
是否在内存中(LRU最近最少使用算法)中有图
Return
文件中获取(加入到内存当中)
开启网络下载,网络下载过程中成功下载图片储存到内存当中,储存到本地当中
通过bitmap.compress写入文件
有一个数列,奇数个,其中有3个是单个的, 其它都是成对的,怎么找出其中任意一个单个的数
public static void singleNum(){
int a[] = new int[]{5,-2,4,4,5,3,-9,-2};
//记录不用参加比较的索引
int b[] = new int[a.length/2];
int i=0;
int piv = a[0];
int j=1;
int n=0;
while(j<a.length){
if(piv==a[j]){
i++;
piv = a[i];
b[n] = j;
n++;
j=i+1;
}else if(contains(b,j)){
i++;
piv=a[i];
}else{
j++;
}
}
System.out.println("单个的数为:"+ piv);
}
/**
* 判断是否包含
*/
public static boolean contains(int a[],int num){
for(int i=0;i<a.length;i++){
if(a[i] == num){
return true;
}
}
return false;
}
在一个数组中,找出出现次数最多且数值最大的一个数并输出
public class HashMapTest1
{
/**
* 找出一个数组中一个数字出现次数最多的数字
* 用HashMap的key来存放数组中存在的数字,value存放该数字在数组中出现的次数
* @author xiaoluo
*/
public static void main(String[] args)
{
int[] array = {2, 1, 2, 3, 4, 5, 2, 2, 2, 2};
//map的key存放数组中存在的数字,value存放该数字在数组中出现的次数
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i = 0; i < array.length; i++)
{
if(map.containsKey(array[i]))
{
int temp = map.get(array[i]);
map.put(array[i], temp + 1);
}
else
{
map.put(array[i], 1);
}
}
Collection<Integer> count = map.values();
//找出map的value中最大的数字,也就是数组中数字出现最多的次数
int maxCount = Collections.max(count);
int maxNumber = 0;
for(Map.Entry<Integer, Integer> entry : map.entrySet())
{
//得到value为maxCount的key,也就是数组中出现次数最多的数字
if(maxCount == entry.getValue())
{
maxNumber = entry.getKey();
}
}
System.out.println("出现次数最多的数字为:" + maxNumber);
System.out.println("该数字一共出现" + maxCount + "次");
}
}
怎么样的类可以作为hashmap的键
容器装的都是Object的,需要Integer,Double这些类
进程和线程之间的联系与区别
定义:进程是具有一定独立功能的程序关于某个数据集合上的一次运动活动,进程是系统进行资源分配和调度的一个独立单位,一个正在运行的程序
线程是进程的一个实体,在CPU调度和分配的基本单位,它是比进程更小的独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点再运行中必不可少的资源,但是它可与同属一个进程的其他线程共享进程所拥有的全部资源,进程的执行单元,一条执行路径
多线程:就是指应用程序有多条执行路径
关系:一个线程可以创建和撤销另一个线程,同一个进程中的多个线程直接可以并发执行
区别:一个程序至少有一个进程,一个进程至少有一个线程;
线程的划分尺度小于进程,使得多线程程序的并发性高;
进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率;
线程在执行过程中与进程还是有区别的,每个独立的线程有一个程序运行的入口,顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序当中,由应用程序提供多个线程执行控制;
多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,开始实现进程的调度和管理以及资源分配
Intent的用途,以及IntentService
Intent意图:描述要来干什么
显示意图:对于明确指出目标组件名称的
隐式意图:没有明确指出目标组件名称的
IntentService:是Service的子类,用来处理异步请求,客户端通过StartService的方法传递请求给IntentService,IntentService在onCreat()函数中通过HandlerThread单独开启一个线程来处理所有Intent请求对象,以免事务处理阻塞主线程,执行完所有的一个Intent请求对象所对应的工作之后,如果没有新的Intent请求达到,则自动停止Service,否则执行下一个Intent请求所对应的任务,每次只会执行一个工作现场,执行完第一个之后再执行第二个。
优点:Activity的进程,当处理Intent的时候,会产生一个对应的Service
Android的进程处理器会尽可能的不kill掉
容易使用
广播创建方式有几种?有什么区别?
两种方式:
常驻型,当程序关闭之后,如果信息广播来,程序也会被系统调用自动运行
不是常驻型,广播随着程序的生命周期开启和结束
AIDL的全程
Android interface definition language安卓接口定义语言
Aidl的文件都是公有的,没有访问权限的修饰
如何收集软件崩溃信息
1.log 2.写本地文件 3.友盟收集
自定义控件相关
1.继承已有的控件实现自定义
2.继承View onMeasure onLayout onDraw
Listview下拉刷新和分页加载的实现机制
当用户滑到listview最后一项是,通知异步线程进行加载下一页的数据,下一页加载完成之后调用adapter的notifydatasetchanges()方法或者调用ListView的onScroll
Activity的启动模式和Flag标记
Standard:标准模式,这是系统的默认模式。每次启动Activity都会重新创建一个新的实例,不管这个实例是否已经存在
singleTop:栈顶复用模式,这种模式下,如果新的Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建
SingleTask:栈内复用模式:这是一种单例模式,在这种情况下,只要有Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例
SingleInstance:单实例模式:这个是一个增强的singleTask模式,那就是具有此种模式的Activity只能单独位于一个任务栈中。
Activity的Flag:
FLAG_ACTIVITY_NEW_TASK:这个标记位的作用是为Activity指定"singleTask"启动模式,其效果和在XML中指定该启动模式相同;
FLAG_ACTIVITY_SINGLE_TOP:这个标记位的作用是为Activity指定"singleTop"启动模式,其效果和在XML中指定该启动模式相同;
FLAG_ACTIVITY_CLEAR_TOP:具有此标记位的Activity,当它启动时,在同一个任务栈中所有位于它上面的Activity都要出栈;
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有这个标记的Activity不会出现在历史Activity的列表中,当某些情况下我们不希望用户通过历史列表回到我们的Activity的时候这个标记比较有用。它等同于在XML中指定Activity的属性"android:excludeFromRecents="true""
通过Intent传递一些二进制数据的方法有哪些
1.使用Serializable接口实现序列化
2.实现Parcelable接口
Android dvm的进程和Linux的进程,应用程序的进程是否为同一个概念
DVM指Dalvik的虚拟机,每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例,而每一个DVM都是Linux中的一个进程,所以是同一个概念。
View的刷新
需要刷新的地方使用handle.sendmessage发送信息,然后再handle的getmessage里面执行invalidate或者postinvaliate
说说MVC模式的原理
M,model 是应用程序的主体部分,所有的业务逻辑都应该写在这一层,对数据库的操作,对网络等操作都在model层,对业务计算等操作也是必须放在这一层
V,view 是应用程序中负责生产用户界面的部分
C,control 是根据用户的输入,控制用户界面数据显示以及更新model对象的状态部分。通常落在Activity肩上
横竖屏切换的Activity的生命周期
1.不设置切横屏会执行一次,切竖屏会执行两次
2.设置activity的android:configChanges=“orientation”切屏重新调用生命周期,切换横竖屏都只会执行一次,但是竖屏最后多打印一个onConfigurationChanged();
3.设置Activity的android:configChanges=“orientation|keyboardHidden”时,切换不会重新调用各个生命周期,只会执行inConfigurationChangeed(),横屏一次,竖屏两次
如何将SQLite数据客户与apk文件一起发布
可以将文件复制到res aw目录中,所有在res aw的目录中的文件都不会被压缩,这样可以直接提该目录中的文件,可以将db文件复制到res aw目录中
谈谈安卓里面的ipc机制
Ipc是内部进程通信的简称,是共享“命名管道”的资源,Android中的IPC机制是为了让Activity和Service之间可以随时的进行交互,通过定义AIDL接口文件来定义IPC接口,Service端实现IPC接口,Client端调用IPC接口本地代理
NDK是什么
NDK是一系列工具的集合,帮助开发者迅速的开发C/C++的动态库,并能自动将so和java应用打包成apk包
NDK集成了交叉编译器,并提供了相应的mk文件和隔离cpu
简单描述一下Android的系统框架
Android的系统框架从上往下为Linux内核层,运行库,应用程序框架层和应用程序层
Activity被重新创建后恢复缓存数据方法
onSavaInstanceState()和onRestoreInstanceState();方法
Android的Service的生命周期
1.采用Context.StartService方法
onCreate onStart onDestory
onCreate该方法在服务被创建的时调用,该方法只会被调用一次,无论调用多少次startService或者bingService,服务也只会被创建一次
onStart只有采用Context.startService方法启动服务时才会回调该方法,该方法在服务开始运行时被调用,onStart方法会被多次调用
onDestory方法在服务被终止的时候调用
2.采用Context.bindService方法启动服务有关的生命周期方法
onCreate onBind onUnbind onDestory
onBind只有在Context.bindService方法启动服务时候才会回调该方法,该方法在调用者和服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService的方法并不会导致该方法被多次调用
onUnbind只有采用Context.bindService方法启动服务的时候才会回调该方法。触发生命周期如下
onCreate onStart onBind onUnbind onRebind
Application类的作用
要在android使用全局变量就可以使用Application的context
Synchronized关键字
保证了多个线程对于同步块是互斥的,synchronized作为一种同步手段,解决java线程的执行有序性和内存可见性
设计模式(面向对象 闫红) 数据结构+算法(java版)线程的并发编程 操作系统和组成原理
创建线程的方式
有2中
方式1:继承Thread类
A.定义一个类继承Thread类
B.子类要重写Thread类的run()方法
C.让线程指定执行
启动线程并执行,是不能使用run()方法的,这个时候需要使用start(),这个方法其实做了两件事情,第一,让线程启动 第二,自动调用run()方法
方法2:实现Runnable接口
A.创建一个类实现Runnable接口
B.重新run()方法
C.创建类的实例
D.把类的实例作为Thread的构造参数传递,创建Thread对象
两种方法的区别:1.避免单继承的局限性 2.实现接口的方式,只创建了一个资源对象,更好的实现了数据和操作的分离
为什么要使用线程?什么时候使用?
为了提高效率才使用,只要当要操作的代码的内容比较多,比较耗时,循环次数较多的情况才使用
线程执行的随意性
程序的执行,其实是抢占CPU的资源,CPU是在多个程序之间做着高效的切换。
线程的生命周期:
线程的随机性和延迟性,导致线程共享数据出现了问题。
解决方法:
在多线程程序中,一般来说不是所有的代码都有问题,所有我们只需要找到那些可能出现问题的代码,把可能出现问题的代码,给包起来,看做一个整体,只有这个整体完毕,别人才能继续访问。为了安全,把整个包起来的代码加个锁给锁起来。
怎么找:1.看没有有共享数据 2.看对共享数据的操作是不是多条语句 3.看是不是在多线程程序中
怎么锁:synchronized(所对象){
需要被锁的代码} 多个线程必须使用同一把锁
同步代码快的锁是任意的对象
同步方法锁对象是this对象
静态方法的锁对象是 类的字节码文件对象
被同步的内容越少越好,所以一般使用同步代码块
如果一个方法内部全部同步了,可以考虑使用同步方法
线程间的通信
不同种类的线程间对共享数据的操作问题
线程的优先级
getPriority()获取线程的优先级,默认是5,范围是1到10.在一定程度上,让线程获得较多的执行机会
Yield:
尽可能暂停当前正在执行的线程对象,并执行其他线程,是为了让线程更加和谐,但不要依赖,如果要实现真正的数据依次数据就需要等待唤醒机制
Join(加入线程)
一旦有join()线程,那么其他线程必须都等待,知道该线程结束
setDaemon(守护线程)
将该线程标记为守护线程或者用户现在,当正在运行的线程都是守护线程时,java虚拟机退
出。该方法必须在启动线程前调用。一旦主线程结束,那么守护线程就结束了
生产者/消费者模式
生产者/消费者模式其实是一个很经典的线程同步模型,很多时候,并不是光保证多个线程对某共享资源操作的互斥行就够了,往往多个线程之间都有协作的。
假设有这样一种情况,有一个桌子,桌子上面有一个盘子,盘子里面只能放一颗鸡蛋,A专门往盘子里面放鸡蛋,如果盘子有鸡蛋,则一直等到盘子里面没有鸡蛋,B专门从盘子里面拿鸡蛋,如果盘子里面没有鸡蛋,则等待直到盘子里面有鸡蛋。其实盘子就是一个互斥的区域,每次往盘子里面放鸡蛋应该是互斥的,A的等待其实就是主动放弃县城所,B等待时候还要提醒A放鸡蛋。
声明一个Plate对象,被线程A和线程B共享,A专门放鸡蛋,B专门拿鸡蛋。假设:
A.开始,A调用plate.putEgg方法,此时eggs.size()为0,因此顺利将鸡蛋放到盘子,海之星了notify()方法,唤醒锁的阻塞队列的线程,此阻塞队列还没有线程。
B.又有一个A线程对象调用plate.putEgg方法,此时eggs.size()不为0,调用wait()方法,自己进入了锁对象的阻塞队列
C.此时,又来了一个B线程对象,调用plate.getEgg()方法,eggs.size()不为0,顺利的拿到了一个鸡蛋,还执行了notify()方法,唤醒锁的阻塞队列的线程,此时阻塞队列有一个A线程对象,唤醒后,它进入到就绪队列,就绪队列就它一个,因此马上得到锁,开始往盘子里面放鸡蛋,此时盘子都是空的,因此放鸡蛋成功
Volatile关键字
是java提供的一种同步手段,只不过它是轻量级的同步,因为volatile只能保证多线程的内存可见性,不能保证多线程的执行有序性
在Android当中,简述一下jni的调用过程
A.安卓和下载cygwin,下载Android sdk
B.在ndk项目中JNI接口的设计
C.使用c/c++实现本地方法
D.JNI生产动态链接库so文件
E.将动态链接库复制到java工程,在java工程中调用,运行java工程
Android应用程序结构有哪些
Linux内核,系统运行库,开发框架包,核心应用程序
如何打开res aw目录中的数据库文件
在Android中不能直接打开res aw目录中的数据库文件,而需要在程序第一次启动的时候将该文件复制到手机内存或是SD卡的某个目录中,然后再打开该数据库文件。复制的基本方法是使用getResource().openRawResource方法获得res aw目录中的资源的InputStream对象,然后将该InputStream对象中的数据写入其他的目录中相应的文件中,在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法来打开任意目录的SQLite数据库文件
Android的储存方式
A.采用SharePreference储存数据,只能在同一个包内使用,不能不同包之间使用
B.文件存储数据:采用openFileInput()和openFileOutout()方法
C.SQLite数据库存储数据
D.使用ContentProvider存储数据:主要应用于程序之间进行数据交换,从而能够让其他应用保存或者读取此Content Provider的各种数据类型
E.网络存储数据
Android中Activity,Intent,Content Provider,Service各有什么不同
Activity:活动窗体,是最基本的Android应用组件,一个活动就是一个单独的屏幕,每一个活动窗体就是一个单独的屏幕,每个活动都被实现为一个独立的类,并且从活动基类中继承而来
Intent:意图,描述应该干什么。最重要的部分是动作和动作对应的数据
Content Provider:内容提供器,Android应用程序能够将它们的数据保存到文件,SQLite数据库中,甚至是任何有效的设备中。
Service:服务,具有一段较长生命周期且没有用户界面的程序
Android:gravity与Android:layout_gravity的区别:
前者是让EditText中的文字在EditText组件中居中显示
后者是让EditText组件在LinnerLayout中居中显示
同步静态和非静态的区别:
静态方法声明必须有static,调用的时候使用类名+.+静态方法名方式
非静态方法不能使用static关键字,调用的时候需要初始化该方法所属的类
本质区别:静态方法在程序初始化之后一直会贮存在内存中,不会被垃圾回收器回收。非静态方法只在该类初始化后贮存在内存中,当该类调用完毕后会被垃圾回收器回收。
同步静态方法和同步非静态方法的异同
所有的非静态方法用的都是同一把锁——实例对象本身,也就是说如果一个实例对象的非静态同步方法获取锁后,该实例对象的其他非静态同步方法必须等待
如有有个100M大的文件,需要上传至服务器中,而服务器form表单最大只能上传2M可以用什么方法:
首先使用http协议上传数据,将我们的数据进行解析组拼成字符串,以流的方式发送到服务器当中,且上传文件用的都是post,因为post方式对大小没有限制。
假设可以每次真的只能上传2m,那么可能我们只能把文件切断,然后分别上传。
AsyncTask使用在那些场景?它的缺陷是什么?如何解决?
是比Handler更轻量级(只是代码轻量级,而实际上要比handler更耗费资源),适用于简单的异步处理
需要一些好使操作,耗时操作完成后更新主线程,或者在操作过程中对主线程的UI进行更新。
缺陷:一个AsyncTask中维护着一个长度为128的线程池,同时可以执行5个工作线程,还有一个缓冲队列,当线程池已有128个线程,缓冲队列已满是,如果在提交任务就会抛出RejectedExecutionException
解决:由一个控制线程来处理AsyncTask的调用判断线程池是否满了,如果满了则线程睡眠否则继续处理
AsyncTask定义了三种泛型类型:Params,Progress和Result
Params:启动任务执行的输入参数
Progress:后台任务的百分比
Result:后台执行任务最重返回的结果
至少要重写以下两个方法:
doInBackGround(Params...)后台执行,比较耗时的操作都可以放在这里,这里不能直接操作UI,此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间,在执行过程中可以调用publicProgress(Progress..)来更新任务的进度
onPostExecute(Result)相当于Handler处理UI的方式
同步和异步的使用场景:
如果数据将线程间共享,列如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行共享存储。当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程。
Android下Context,Activity,Application之间有什么区别
首先Activity和Application都是Context的子类。Activity和Application维护的生命周期不一样,前者维护的是一个Activity的生命周期,而对应的Context也只能访问该Activity内的各种资源。后者是维护Application的生命周期。Application的Context只针对整个应用。
注意内存泄露,防止内存泄露应该注意以下几个方面:
A.不要让生命周期长的对象引用Activity context,即保证引用Activity的对象要与Activity本身的生命周期是一样的
B.对于生命周期长的对象,可以使用Application context
C.避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化
如果Android需要用到一些全局变量,可以引用Application这个类,在Activity中可以使用getApplication()方法获得实例。
IPC是什么?
IPC是内部进程通信的简称,是共享“命名管道”的资源,Android中的IPC机制是为了让Activity和Service直接可以随时的进行交互,故在Android中,该机制,只适用于Activity和Service之间的通信。通过定义了AIDL接口文件来定义IPC接口。
接口和抽象类的区别:
接口是对动作的抽象
抽象类是对根源的抽象
抽象类表示的是这个对象是什么
接口表示的是这个对象能做什么
A.接口是抽象类的变体,接口中所有方法是抽象的
B.接口可以多继承,抽象类不行
C.接口定义方法,不能实现,抽象类可以实现部分方法
D.接口中基本数据类型为static,而抽象类不是
5868



被折叠的 条评论
为什么被折叠?



