2016 最新Android面试题库

技术负责人:Android源码中有哪些用到了设计模式?
我:比如dialog的设置,用的是build设计模式,Bitmap用的是工厂设计模式
技术负责人:如果要你设计一个计算器,你从设计模式的角度看,应该怎么设计呢?
我:写一个接口,定义一个方法,传入俩参数,返回一个得数,具体的实现写在实现类中,然后用工厂设计模式,要什么方法就生产什么类来实现。
技术负责人:IO流中有一些流为了性能更好,我们要定义一个缓存,API中自己实现缓存的是什么?
我:ByteArrayOutPutStream,先把数据存到内存,再一次输出 。
技术负责人:内存溢出怎么检查?
我:DDMS中有一个heap可以查看进程的内存占用情况,可以通过它来检查页面,也有一个插件mat可以很详细的看到具体每一个对象的内存占用情况。
技术负责人:通常怎么导致内存溢出?
我:内存泄露,比如某一个长期存在的对象引用了某个Activity,那么当Activity关闭的时候,它占用的内存并不会被释放。还有就是内存占用过多,比如加载一张很大的图片。
技术负责人:如果我要你加载一个1080p的图片呢?
我:那可以根据屏幕的分辨率来压缩图片,因为超过屏幕分辨率的图片显示在屏幕上效果是一样的。还可以开一个进程去专门处理这个请求,一个app可以申请十个进程,而每个进程都有16、32这样的默认app的内存大小。
技术负责人:你的网络实现是怎么实现的?
我:一开始是自己用线程池封装一下android的网络API,然后调用,后来用的是volley等实现,最后用的是Retrofit。
技术负责人:知道断点下载么?
我:(这个问题很热门啊,我当时说了下断点下载和多线程下载的原理,黑马教程中有,上个月梁老师的面试贴中也有,我就不写了)
技术负责人:对于屏幕适配有什么了解?
我:一个是可以在代码中动态设置控件大小,一个是设置多个分辨率的图片,用9patch图片,单位用dp,一个是用fragment来适配不同大小的屏幕
笔试题:
1.说说你知道的设计模式有哪些?对你熟悉的设计模式做重点介绍?
按照目的来分,设计模式可以分为创建型模式、结构型模式和行为型模式。
创建型模式用来处理对象的创建过程;结构型模式用来处理类或者对象的组合;行为型模式用来对类或对象怎样交互和怎样分配职责进行描述。

创建型模式用来处理对象的创建过程,主要包含以下5种设计模式:
? 工厂方法模式(Factory Method Pattern)
? 抽象工厂模式(Abstract Factory Pattern)
? 建造者模式(Builder Pattern)
? 原型模式(Prototype Pattern)
? 单例模式(Singleton Pattern)

结构型模式用来处理类或者对象的组合,主要包含以下7种设计模式:
? 适配器模式(Adapter Pattern)
? 桥接模式(Bridge Pattern)
? 组合模式(Composite Pattern)
? 装饰者模式(Decorator Pattern)
? 外观模式(Facade Pattern)
? 享元模式(Flyweight Pattern)
? 代理模式(Proxy Pattern)

行为型模式用来对类或对象怎样交互和怎样分配职责进行描述,主要包含以下11种设计模式:
? 责任链模式(Chain of Responsibility Pattern)
? 命令模式(Command Pattern)
? 解释器模式(Interpreter Pattern)
? 迭代器模式(Iterator Pattern)
? 中介者模式(Mediator Pattern)
? 备忘录模式(Memento Pattern)
? 观察者模式(Observer Pattern)
? 状态模式(State Pattern)
? 策略模式(Strategy Pattern)
? 模板方法模式(Template Method Pattern)
? 访问者模式(Visitor Pattern)

单例模式实现1:
public class Singleton {
    // 类共享实例对象
    private static Singleton singleton = null;
    // 私有构造方法
    private Singleton() {
        System.out.println("-- this is Singleton!!!");
    }
    // 获得单例方法
    public synchronized static Singleton getInstance() {
        // 判断 共享对象是否为null ,如何为null则new一个新对象
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

单例模式实现2:
public class Singleton {
    // 类共享实例对象 实例化
    private static Singleton singleton = new Singleton();
    // 私有构造方法
    private Singleton() {
        System.out.println("-- this is Singleton!!!");
    }
    // 获得单例方法
    public static Singleton getInstance() {
        // 直接返回共享对象
        return singleton;
    }
}
2.String和StringBuffer有什么区别?在什么情况下使用它们?
String:
是对象不是原始类型.
为不可变对象,一旦被创建,就不能修改它的值.
对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.
String 是final类,即不能被继承.

StringBuffer:
是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象
它只能通过构造函数来建立.

效率比较:StringBuffer比String高。因为StringBuffer有预留空间一直追加,只是对一个对象进行操作。而String是不能被修改的,只能重复的去创建对象来实现修改。——如果频繁的对字符串进行追加、替换、修改、插入、删除操作,最好使用StringBuffer。如果必须用String可以使用StringBuffer调用toString()来转换成String即可。
3.handler机制的原理?
Handler 是一个消息分发对象。而消息分发,有赖于消息循环,也就是 Looper。在一个线程中,Looper 阻塞线程,等待消息构成循环,有了消息,分配到对应的 Handler,让他进一步分发处理,如是。
4.什么是MVC?
 MVC(Model/View/Controller)模式是国外用得比较多的一种设计模式,分为:
 1、模型(Model) 
 2、视图(View) 
 3、控制器(controller) 
模型-视图-控制器(MVC)是80年代Smalltalk-80出现的一种软件设计模式,现在已经被广泛的使用。 
1、模型(Model) 

模型是应用程序的主体部分。模型表示业务数据,或者业务逻辑. 

2、视图(View) 

视图是应用程序中用户界面相关的部分,是用户看到并与之交互的界面。 

3、控制器(controller) 

控制器工作就是根据用户的输入,控制用户界面数据显示和更新model对象状态。 

5.Activity的生命周期?
Activity中有fvc7个与生命周期有关的函数。其中onCreated()是activity第一次被启动时执行的,主要是初始化一些变量,onRestart()是当前activity重新被启动时调用的;绑定一些监听器等;onStart()是activity界面被显示出来的时候执行的;onResume()是当该activity与用户能进行交互时被执行;onPause()是另一个activity被启动,当前的activity就被暂停了,一般在该函数中执行保存当前的数据;onStop()表示另一个activity被启动完成时,当前activity对用户同时又完全不可见时才调用的;onDestroy()是退出当前activity时调用的,当然如果程序中调用finish()或者说android系统当前资源不够用时就会被调用。
当用多个activity在执行时,这时候android系统会自动将这些activity压入栈中并且总是显示最顶的那个activity,这个栈在android叫做task,但是这个栈只支持压入和弹出操作,不支持排序插入等操作。
Activity的7个生命周期函数中的onStop()函数被调用时是在其对应的activity被另外的activity完全遮挡的时候,如果只有部分遮挡,则不会被调用。部分遮挡一般是以消息activtiy的形式出现,这个只需在AndroidManifest.xml中将其对于的activity的主题设置theme中更改即可。
这7个周期函数,当系统资源不够时,其中onPause(),onStop(),onDestroy()是有可能被系统kill掉的,但其它4个是不会被kill掉。
6.Activity有哪几种启动模式,请简要介绍他们分别的适用场景?
当应用运行起来后就会开启一条线程,线程中会运行一个任务栈,当Activity实例创建后就会放入任务栈中。Activity启动模式的设置在AndroidManifest.xml文件中,通过配置Activity的属性android:launchMode=""设置。

1. Standared模式(默认)
我们平时直接创建的Activity都是这种模式的Activity,这种模式的Activity的特点是:只要你创建了Activity实例,一旦激活该Activity,则会向任务栈中加入新创建的实例,退出Activity则会在任务栈中销毁该实例。

2. SingleTop模式
这种模式会考虑当前要激活的Activity实例在任务栈中是否正处于栈顶,如果处于栈顶则无需重新创建新的实例,会重用已存在的实例,否则会在任务栈中创建新的实例。

3. SingleTask模式
如果任务栈中存在该模式的Activity实例,则把栈中该实例以上的Activity实例全部移除,调用该实例的newInstance()方法重用该Activity,使该实例处於栈顶位置,否则就重新创建一个新的Activity实例。

4. SingleInstance模式
当该模式Activity实例在任务栈中创建后,只要该实例还在任务栈中,即只要激活的是该类型的Activity,都会通过调用实例的newInstance()方法重用该Activity,此时使用的都是同一个Activity实例,它都会处于任务栈的栈顶。此模式一般用于加载较慢的,比较耗性能且不需要每次都重新创建的Activity。
16:
笔试题:
1.进入多个Activit后如何一次退出?
市面上普通的方法是抛出异常,或者在每个activity的onDestroy方法中循环退出。我是通过创建一个ActivityCollector类,管理activity。其中有addActivity,removeActivity和finishAll三个方法。再创建一个BaseActivity去让所有的activity继承。在 onCreate方法中调用ActivityCollector的addActivity,onDestory方法中调用removeActivity方法。最后在你想要一键退出程序的地方调用finishAll方法即可。
2.注册广播接收器的方式,谈谈优缺点与优先级?
首先写一个类要继承BroadcastReceiver
第一种是在配置文件里面进行静态注册,第二种是在代码中进行动态注册

两种注册类型的区别:
静态注册是当程序关闭后,如果有广播发过来,还能启动程序
动态注册的生命周期跟程序的生命周期是一样的,程序关闭后动态注册的广播是不能再接收到广播的

动态注册的优点:在Android的广播机制中,动态注册的优先级高于静态注册的优先级,因此在必要情况下,我们需要动态注册广播接收器。
静态注册的优点:动态注册广播接收器还有一个缺点就是当用来注册广播的Activity关闭后,广播也就失效了,同时反映了静态注册广播的一个优势,就是无需担心广播接收器是否关闭,只要设备处于开启状态,广播接收器就能接收。
3.代码混淆有什么作用?哪些代码不能混淆,为什么?
混淆器的作用不仅仅是保护代码,它也有精简编译后程序大小的作用。
     Android系统组件,系统组件有固定的方法被系统调用。

  被Android Resource 文件引用到的。名字已经固定,也不能混淆,比如自定义的View 。

  Android Parcelable ,需要使用android 序列化的。

  其他Anroid 官方建议 不混淆的,如

  android.app.backup.BackupAgentHelper
  android.preference.Preference
  com.android.vending.licensing.ILicensingService
  Java序列化方法,系统序列化需要固定的方法。

  枚举 ,系统需要处理枚举的固定方法。

  本地方法,不能修改本地方法名

  annotations 注释

  数据库驱动

  有些resource 文件

  用到反射的地方
4.Property Animation与Tween Animation的区别?
Tween动画通过view的matrix和alpha变量对view进行修改,但是并不会修改view自身属性。
而Property动画会修改view的自身属性,动画结束后的效果会实实在在的反应在view上。

5.如何解决ListView中加载大量图片的内存溢出问题?请详细谈谈解决思路。
方法一:
在从网络或本地加载图片的时候,把其变为缩略图。
方法二:
运用JAVA的软引用,进行图片缓存,将经常需要加载的图片放在缓存里,避免重复加载。
方法三:
使用第三方框架:volley,xUtils,Fresco等图片缓存框架。

项目经理:那你们消息的推送是用的pull还是push,你是怎么选择的?
我:要获取服务器上不定时更新的信息,一般来说有两种方法:
第一种是客户端使用Pull的方式,就是隔一段时间就去服务器上获取一下信息,看是否有更新的信息出现。
第二种就是 服务器使用Push的方式,当服务器端有新信息了,则把最新的信息Push到客户端上。这样,客户端就能自动的接收到消息。
虽然Pull和Push两种方式都能实现获取服务器端更新信息的功能,但是明显来说Push方式比Pull方式更优越。
因为Pull方式更费客户端的网络流量,更主要的是费电量,还需要我们的程序不停地去监测服务端的变化。(面试官在点头)
项目经理:那你已经打开过这个app了,正在使用,现在后台配置的应用下载变化了,你是怎么做的这个动态变化?
我:这个问题我们也考虑到了,这就用到了上面提到的消息通知。服务端会推送一个应用推荐改变的消息,携带一个状态码,当客户端接收到这个消息后,识别状态码,然后会主动地向服务端发起一个请求应用推荐列表的消息的请求。此时会刷新应用推荐的界面。
项目经理:xutils的多线程断点下载怎么实现的?
我:(这部分黑马的课程里有提过,还很详细)其实之前我有研究过xutils的源码,多线程那一部分其实没太大的难度,用的是线程池的技术。我讲一下断点下载的思路吧。下载断开之后,问题是在于怎么从上一次断开的位置继续下载。因为下载的流可以设置起始位置,那么问题就转化为,你如何知道上一次下载了多少?换句话说下载了多少个byte?xutils用的是一个临时文件记录下载的byte数值,下载完毕把这个临时文件给删除掉,下次对同一文件启动下载的时候,去判断是否存在这个临时文件,存在就意味着断点下载,接着就读取里面的数值,设置下载的起始点就可以了。基本实现原理是这样。(面试官其实也不一定知道原理,但看得出来,他对哥这答案挺满意)
项目经理:嗯。在上家公司待了多久(面试官看来已经不打算面我技术了),为什么这个时候想离开?
面试官:#魅族和华为这两种机型是很特殊的机型,经常会有一些很奇葩的UI bug,你能不能讲讲你遇到的bug
我:#我记得之前有一个这样的bug,在魅族手机上,ListView的Item中的EditText无法编辑,点击EditText弹出软键盘后,软键盘会立即自动隐藏,当时在别的机型上测试没问题,一直找不出原因,只在魅族上存在这个问题,非常地奇怪
面试官:#那后来怎么解决的呢?
我:#将ListView换成RecyclerView,这个问题就不存在了。

一、任务做不完的时候,怎么办?
我当时想,如果真做不完了只好加加班了。但是他想知道的肯定不仅仅是做不完的答案,而是通过这个问题看看你实际的经验。
于是我说,我一般会在项目初期,做项目开发计划的时候。采取一些预防措施:
1、比如在预估时间上,根据实际情况并且考虑到需求变化、除了写代码,人还要开会等(一天的coding时间其实没有足8小时)。所以一般会在预估开发周期的时候把完成任务的时间预算提高两倍。
2、在做程序设计的时候,我就把模块细分成最小的功能点,做好甘特图了,这样能保证每天完成一个可以测试的功能点。
3、稳健就是快捷,我开发不迷信什么快速开发。做好每个接口的单元测试,健壮、封装良好的代码才能保证项目的稳定开发。
4、如果以上的东西都没法保证项目进度的时候,只能选择加班了。但这也说明了这个项目当时的准备和计划并没有做好。
面试听完后对我这些话点头表示赞同。接着问了第二个问题:
二、能不能独立开发?
我的回答:虽然上家公司是两个人开发,但我们都是划分好独立模块的,我觉得只要能独立开发好一个模块,那么组成一个APP做独立开发,我觉得我可以胜任!
项目经理:你们平时有遇到一些oom么?
我:有的,oom一般是在处理大图片,和网络请求的时候会经常遇到。(先从总体上说一下,但是要留有余想,一般情况下是这样的,是不是还有特殊的情况,这就叫牵着鼻子走)。但是我认为(要突出我,这样显得自信。),我们应该更多的从java的逻辑思考代码,要养成良好的编程习惯,比如:我们尽量要少用hashmap ,因为hashmap,会另外使用一个单独的区域存储mappIng映射。要多使用arrymap,他没有这个问题,或者使用sparsearay稀疏数组,这个可以减少对象的装箱操作。比如,还有我们要少使用一些enum,枚举的类型,因为adroid的官方文档(始终站在android的角度)上已经说明使用枚举会申请两倍的内存。还有bitmap类型,两种缩放图片等。
项目经理:你给我讲讲你项目的架构?
我:旁白:(这个东西,上来很容易把人吓一跳!),这个时候千万淡定,这个题目的频率还是挺高的。很多人对android中的框架有这样或者那样的理解,其实上,android中的框架和javaweb中不同,我们知道javaweb有spring,hurbenet,strust,但是android和他们不一样,他没有这些明显的框架。我理解的android的框架(凸显我)就是:我们在拿到需求后(多说一些关键的专业名词),拿到项目原型图后,开始着手做项目之前要首先布局好的代码。
这里面,我认为第一个需要考虑的问题是这四个方面:第一是网络请求,第二是数据库的管理(包括一些持久化),第三呢是:三级缓存的使用和大图片加载。第四呢是:ui框架相关的部分。
除了这个我认为还需要考虑的是——刚才那四部分,待会回来讲——公共类,你比如说baseaplication ,baseActivity,baseFragment,这些共有类,父类,里面的一些操作是固定的。比如:我们在baseaplication ,初始化一些数据,绑定一些context,我们在baseActivity,里面管理线程,使用线程池,管理请求,或者复写他的返回键。(一定要结合项目)这些东西。
另外我们:还需要工具类,这些工具类,包括一些dip转px的东西,一些数据类型转换需要的,比如数组转集合。
当我们考虑一个应用需要的基本部分的时候,比如网络请求,是我们主要考虑的部分,我们可以利用andorid 原生的httpurlconection,但是他不是很好用,功能不够强大,调用麻烦。所以一般不怎么使用,还有一个是httpclient,他是apppchi公司提供的一个,andorid集成到系统中的,但是android 6.0之后(一定要提些新技术)。已经不提供这些api了(显的自己很关心新技术好学)。,,,,
网络上还有一些第三方的,我么有时候要赢,节约成本(很多公司喜欢这种能为公司考虑的园林工),例如:afinal volloy ,okhttp。这些框架分别有以下特点,我们要根据,,,你比如商城,,,他有请求频繁,请求量不大的特点,,我们可以用vollery。
6:
1、问自己做的项目,蓝牙、LED、WIFI等和硬件对接的项目
答:        蓝牙和LED都是硬件已经搞定了,提供一个接口给我,然后我通过接口来读写硬件。WIFI的话,就是直接仿照的系统的WIFI功能,连接扫描管理什么的,所以我就翻了系统的源码,照着实现。

2、询问自己做过的视频项目,都对视频进行了什么操作
答:        一些常规的播放、快进、暂停、获取缩略图等。

3、有对视频进行过什么比如编辑啊裁剪啊等功能么
答:        那倒没有,只是一些视频的播放方面的,不过编辑功能应该也不难,可以尝试下。

4、开始介绍自己公司的项目流程,提到其中的技术难点
        用wifi与硬件对接,获取视频
答:                这个应该没问题,蓝牙、串口、wifi其实都是对数据进行读写,只不过是连接方式、读写方式不同,既然硬件那边已经有了接口,根据接口调用就好了。
        对视频进行编辑,裁剪、滤镜等,滤镜功能已经完成。
答:                裁剪的话虽然我没做过,但是研究一下应该也没什么问题
        对视频进行分享,要求一键分享到朋友圈,不用点击选择微信朋友圈、编辑
答:                用第三方分享,是要设置一些参数,然后启动一个选择分享对象的界面,但是我记得应该是可以不用选择直接分享的,具体的参数需要查一下。如果第三方这边没有这个功能,可以直接和微信那边交互,因为只要求朋友圈嘛,直接调用微信分享应该可以实现。
2、你了解云端么
答        云端其实也就是一些服务器,和云端交互也就是和后台交互,只不过数据的表现形式、存储方式需要一些改变,本质上和普通的后台交互没什么区别。
                                                                                                                                                                                                                                                         
3、对于一些额外的参数,比如说定位、当前的速度,需要写进视频中,应该怎么获取这些数据呢。因为连接wifi的时候是没有网络的。
答:        这样的话可以在传输完视频数据之后,把wifi断开,连上4G,获取地理位置,我们是可以直接操作网络的连接断开的。要获取当前的速度的话,手机肯定是在车上的,我们可以利用传感器获取当前的加速度参数,然后计算出速度。
安卓笔试题:
1、如何定位和避免内存溢出?
方法1 :  等比例缩小图片  

                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 4;

方法2 :  对图片采用软引用,及时地进行recycle()操作

                SoftReference<Bitmap> bitmap;
                bitmap = new SoftReference<Bitmap>(pBitmap);
    if(bitmap != null){

            if(bitmap.get() != null && !bitmap.get().isRecycled()){
                bitmap.get().recycle();
                bitmap = null;
            }
        }

方法3 :  对复杂的listview进行合理设计与编码:
              1.   注意重用Adapter里面的 convertView  以及holder机制的运用   ----- 参考资料: api demo list 14. Efficient Adapter

 public View getView(int position, View convertView, ViewGroup parent) {
 if (convertView == null) {
            v = mInflater.inflate(resource, parent, false);
            final int[] to = mTo;
            final int count = to.length;
            final View[] holder = new View[count];
            for (int i = 0; i < count; i++) {
                holder[i] = v.findViewById(to[i]);
            }
            v.setTag(holder);
        } else {
        }

          2.  上述方法尝试还未成功,可用 lazy loading data   ----- 参考资料:api demo  list 13

方法4 : 单个页面,横竖屏切换N次后 OOM
         1. 看看页面布局当中有没有大的图片,比如背景图之类的。去除xml中相关设置,改在程序中设置背景图(放在onCreate()方法中):
          Drawable bg = getResources().getDrawable(R.drawable.bg);
          XXX.setBackgroundDrawable(rlAdDetailone_bg);
          在Activity destory时注意,bg.setCallback(null); 防止Activity得不到及时的释放

         2. 跟上面方法相似,直接把xml配置文件加载成view 再放到一个容器里,然后直接调用 this.setContentView(View view);方法

         避免xml的重复加载

方法5 : 在页面切换时尽可能少地重复使用一些代码,比如:重复调用数据库,反复使用某些对象等等......

方法6 :Android堆内存也可自己定义大小 和  优化Dalvik虚拟机的堆内存分配 
    注意若使用这种方法:project build target 只能选择 <= 2.2 版本,否则编译将通不过。 所以不建议用这种方式 

    private final static int CWJ_HEAP_SIZE= 6*1024*1024;
    private final static float TARGET_HEAP_UTILIZATION = 0.75f;
    VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);
    VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);
2、什么叫ANR,如何定位和避免ANR?
无响应问题,如果你在activity中有进行耗时长的问题,就会产生这个问题。
 在Android中, Activity Manager 和 Window Manager system services 会监控每个程序的运行,当程序出现如下三种情况的时候就会弹出ANR的提示对话框:        1.用户在进行了一种操作后5秒钟没有响应。        2.broadCastReceiver所进行的操作在10秒内没有完成。        3.Service在20秒内没返回结果。
1.避免在主线程上进行复杂耗时的操作,比如说发送接收网络数据/进行大量计算/操作数据库/读写文件等。这个可以通过使用AsyncTask或者使用多线程来实现。
2.broadCastReceiver 要进行复杂操作的的时候,可以在onReceive()方法中启动一个Service来处理
3.在设计及代码编写阶段避免出现出现同步/死锁或者错误处理不恰当等情况。
3、写一个singleton?
class Singleton {
  private static Singleton s;
  private Singleton(){
   System.out.println("A Singleton Model example");
  }
  public static Singleton getSigleton()
  {
   if(s==null)s=new Singleton();
   return s;
  }
}
4、什么叫observer,画一下observer的模型?
Observer模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
5、五大布局?
android的布局方式有五种,分别是:LinearLayout(线性布局)、FrameLayout(单帧布局)、RelativeLayout(相对布局)、AbsoluteLayout(绝对布局)和TableLayout(表格布局)。
6、Intent和intentServer的区别?
Intent(意图)主要是解决Android应用的各项组件之间的通讯。
Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。
因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。
IntentService:异步处理服务,新开一个线程:handlerThread在线程中发消息,然后接受处理完成后,会清理线程,并且关掉服务。
IntentService有以下特点:

(1)  它创建了一个独立的工作线程来处理所有的通过onStartCommand()传递给服务的intents。

(2)  创建了一个工作队列,来逐个发送intent给onHandleIntent()。

(3)  不需要主动调用stopSelft()来结束服务。因为,在所有的intent被处理完后,系统会自动关闭服务。

(4)  默认实现的onBind()返回null

(5)  默认实现的onStartCommand()的目的是将intent插入到工作队列中
7、写一个代码,获取一个数组中,出现次数最多且数值最大的数?

8、反序一个字符串,要求时间复杂度和空间复杂度最低?
StringBuilder sb = new StringBuilder(str);

System.out.println(sb);

String[] s = str.split(" ");

String[] b = new String[s.length];

String temp = null;

for (int j = s.length - 1, i = 0; j >= 0; j--, i++) {

System.arraycopy(s, j, b, i, 1);

}
9、service的生命周期 ,开启关闭方法?
Service以及描述下它的生命周期:
  Service是运行在后台的android组件,没有用户界面,不能与用户交互,可以运行在自己的进程,也可以运行在其他应用程序的上下文里。
  Service随着启动形式的不同,其生命周期稍有差别。当用Context.startService()来启动时,Service的生命周期依次为:oncreate——>onStartCommand——>onDestroy 当用Context.bindService()启动时:onStart——>onBind——>onUnbind——>onDestroy。
  Service启动方式有两种;一是Context.startService和Context.bindService。
  区别是通过startService启动时Service组件和应用程序没多大的联系;当用访问者启动之后,如果访问者不主动关闭,Service就不会关闭,Service组件之间因为没什么关联,所以Service也不能和应用程序进行数据交互。而通过bindService进行绑定时,应用程序可以通过ServiceConnection进行数据交互。
  在实现Service时重写的onBind方法中,其返回的对象会传给ServiceConnection对象的onServiceConnected(ComponentName name, IBinder service)中的service参数;也就是说获取了serivce这个参数就得到了Serivce组件返回的值。Context.bindService(Intent intent,ServiceConnection conn,int flag)其中只要与Service连接成功conn就会调用其onServiceConnected方法,停用Service使用Context.stopService。
10、36转为8进制,48转为2进制?
44,110000。
其它:Invalidate与PostInvalidate
android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。 
    Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。 
  Android程序中可以使用的界面刷新方法有两种,分别是利用Handler和利用postInvalidate()来实现在线程中刷新界面。
11.怎样将apk安装在模拟器上?
将xxx.apk拷贝到sdk下的adb的路径下,也就是和adb在同一个文件夹然后进入cmd,进入到该路径下,输入adb install xxx.apk,等段时间后即可看到安装成功,也有提示出现。当然前提是你的模拟器一定是要启动好了。 
12.如何避免OOM之压缩?
下面我们就来看一看,如何对一张大图片进行适当的压缩,让它能够以最佳大小显示的同时,还能防止OOM的出现。
BitmapFactory这个类提供了多个解析方法(decodeByteArray, decodeFile, decodeResource等)用于创建Bitmap对象,我们应该根据图片的来源选择合适的方法。比如SD卡中的图片可以使用decodeFile方法,网络上的图片可以使用decodeStream方法,资源文件中的图片可以使用decodeResource方法。这些方法会尝试为已经构建的bitmap分配内存,这时就会很容易导致OOM出现。为此每一种解析方法都提供了一个可选的BitmapFactory.Options参数,将这个参数的inJustDecodeBounds属性设置为true就可以让解析方法禁止为bitmap分配内存,返回值也不再是一个Bitmap对象,而是null。虽然Bitmap是null了,但是BitmapFactory.Options的outWidth、outHeight和outMimeType属性都会被赋值。这个技巧让我们可以在加载图片之前就获取到图片的长宽值和MIME类型,从而根据情况对图片进行压缩。
13Android给TextView设置透明背景圆角边框?
在drawable文件夹下新建一个文件设置背景样式
在drawable文件夹下面新建text_view_border.xml
solid设置填充颜色,颜色值以#80开头表示透明
stroke 设置边框宽度,颜色值
corners设置圆角
14而INVISIBLE和GONE的主要区别是:

当控件visibility属性为INVISIBLE时,界面保留了view控件所占有的空间;

而控件属性为GONE时,界面则不保留view控件所占有的空间。
15.PagerAdapter-FragmentPagerAdapter-FragmentStataePagerAdapter的区别?
1---PagerAdapter(适合页面数量多的)
针对于View视图的装载
2---FragmentPagerAdapter(适合于页面数量少的)
专门针对于fraagment的适配器 继承自 PagerAdapter 
--- 这里使用fragment 所被用户访问过的页面都会被缓存到内存
---这种适配器适合于页面数量不多 且数据操作不多的页面 一般页面过多不使用这种适配器因为很占内存
3--FragmenStatePagerAdapter 继承自 PagerAdapter (策略性的存储方案)
这里不是所用的被用户访问过的fragment会被缓存到内存
只有在当前页面的左右两侧的fragment  这三个fragment会在内存中
并且每访问下个fragment 旧的就会被onDetach 新的会onAttach
16.请简要描述下MVP模式?
model-处理业务逻辑(主要是数据读写,或者与后台通信(其实也是读写数据)),view-处理ui控件,presenter-主导器,操作model和view
17.单例模式最好的写法
public class Singleton {

    private static volatile Singleton instance = null;

    // private constructor suppresses
    private Singleton(){
    }

    public static Singleton getInstance() {
        // if already inited, no need to get lock everytime
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }

        return instance;
    }
}
18.new Thread的弊端如下:
1. 每次new Thread新建对象性能差。
2. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。
3. 缺乏更多功能,如定时执行、定期执行、线程中断。
相比new Thread,Java提供的四种线程池的好处在于:
1. 重用存在的线程,减少对象创建、消亡的开销,性能佳。
2 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
3. 提供定时执行、定期执行、单线程、并发数控制等功能。

1.对于io流,怎么提升读写速度?
字符输入流缓冲区BufferedReader和字符输入流FileReader的区别就是多了个一次读取一行的方法readLine();字符输出流缓冲区BufferedWriter比字符输出流FileWriter多了个换行方法newLine()。
2.Android中的动画有哪几类,它们的特点和区别是什么?
三种,第一种是Tween动画,第二种是Frame动画,第三种是Property动画。Tween动画,这种实现方式可以使视图组件移动、放大、缩小以及产生透明度的变化;另一种Frame动画,传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影;Property动画是指通过改变实际的属性来实现相应的动画效果。
3.如何将Activity设置成窗口的样式?
在清单文件中将对应的Activity的android:theme属性设置为android:theme="@android:style/Theme.Dialog"。
4.注册广播有几种方式,有何优缺点?请谈谈Android引入广播机制的用意。 
第一种方式:静态注册,在Manifest.xml中注册广播,是一种比较推荐的方法,因为它不需要手动注销广播(如果广播未注销,程序退出时可能会出错)。
第二种方式:动态注册,直接在代码中实现,但需要手动注册注销。
Android系统中的广播是广泛用于应用程序之间通信的一种手段,它类似于事件处理机制,不同的地方就是广播的处理是系统级别的事件处理过程(一般事件处理是控件级别的)。灵活运用广播处理机制,在关键之处往往能实现特别的效果。
5.简单介绍一下Service和IntentService?
Service是android四大组件之一,在后台运行,没有界面,比如后台的数据计算,后台音乐播放等。IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作。
6.Android数据存储方式有哪些?
SharedPreference、SQLite数据库存储、File存储、ContentProvider、网络存储。
7.Android的四种启动模式?简单介绍它们的区别。
Activity的启动模式:默认是standard,每次使用intent启动一个Activity,都会创建一个新的实例
SingleTop:一个Activity已经存在实例,并且位于栈顶,而且启动模式是SingleTop的,那么再次启动该Activity时,不会创建新的实例,直接使用栈顶的;一个Activity已经存在实例,但不位于栈顶,即使启动模式是SingleTop的,那么再次启动该Activity
时,还会创建新的实例。
调用已经存在的Activity实例时会自动执行回调方法
     @Override
    protected void onNewIntent(Intent intent) {
        // TODO Auto-generated method stub
        super.onNewIntent(intent);
        Log.i(TAG, "CActivity的启动模式是 SingleTop,已经位于栈顶,不会创建新的实例");
    }
SingleTask:只有一个实例,允许相关联的 Acitivty和它位于同一个任务中,当已经存在该Activity的实例,再次启动时,直接使用已有的,会把其之上的所有的Activity实例销毁。
SingleInstance:只有一个实例,不允许相关联的 Acitivty和它位于同一个任务中,自己单独在一个任务中,当已经存在该Activity的实例,再次启动时,直接使用已有的。
8.Andriod中常用的5种布局?
LinearLayout、RelativeLayout、FrameLayout、TableLayout、AbsoluteLayout。
9.ListView的优化方案,以及加载大图片的优化?
listView优化方案
1、如果自定义适配器,那么在getView方法中要考虑方法传进来的参数contentView是否为null,如果为null就创建contentView并返回,如果不为null则直接使用。在这个方法中尽可能少创建view。
2、给contentView设置tag(setTag()),传入一个viewHolder对象,用于缓存要显示的数据,可以达到图像数据异步加载的效果。
3、如果listview需要显示的item很多,就要考虑分页加载。比如一共要显示100条或者更多的时候,我们可以考虑先加载20条,等用户拉到列表底部的时候再去加载接下来的20条。
通过设置BitmapFactory.Options来压缩大图片。
10.Android中Intent的作用?
Android中的Intent有两大作用。
一:用来启动其他新的Activity。
二:作为传递数据和事件的桥梁。传递数据时的代码有两种:
第一种是:
Intent intent = new  Intent(CurrentActivity.this , OtherActivity.class); 
intent.putExtra(“data” , somedata); 
第二种是新建一个Bundle,再把该Bundle加入intent,如:
Bundle bundle = new Bundle() ; 
bundle.putString(“data” , somedata) ; 
intent.putExtras(bundle)。
11.如何退出Activity?如何安全退出?
直接finish当前Activity即可。
12.Fragment和Fragment之间怎么通信?
在Fragment中定义回调接口,在相关联的Activity中实现,以此间接地与另一个Activity通信。
通过FragmentManager的findFragmentById找到对应的Fragment并与之通信。

1.在android中,请简述jni的调用过程。
1)安装和下载Cygwin,下载 Android NDK;
2)在ndk项目中JNI接口的设计;
3)使用C/C++实现本地方法;
4)JNI生成动态链接库.so文件;
5)将动态链接库复制到java工程,在java工程中调用,运行java工程即可。
2.NDK是什么?
NDK是一些列工具的集合,NDK提供了一系列的工具,帮助开发者迅速的开发C/C++的动态库,并能自动将so和java 应用打成apk包。
NDK集成了交叉编译器,并提供了相应的mk文件和隔离cpu、平台等的差异,开发人员只需简单的修改mk文件就可以创建出so。
3.面向对象设计的6大基本原则简介。
开-闭原则,讲的是设计要对扩展有好的支持,而对修改要严格限制。
里氏代换原则,很严格的原则,规则是“子类必须能够替换基类,否则不应当设计为其子类。”
依赖倒换原则,“设计要依赖于抽象而不是具体化”。
接口隔离原则,“将大的接口打散成多个小接口”。
合成聚合复用原则,设计者首先应当考虑复合/聚合,而不是继承。
迪米特法则或最少知识原则,“一个对象应当尽可能少的去了解其他对象”。
单一职责原则。
4.Android常用的设计模式有哪些?
简单工厂模式、抽象工厂模式、观察者模式、单例模式、适配器模式,建造者模式。
建造者模式最明显的标志就是Build类,而在Android中最常用的就是Dialog的构建,Notification的构建也是标准的建造者模式。
书中以Intent介绍了原型模式,是通过实现Cloneable接口来做的。
静态工厂方法在Android中比较明显的例子应该就是BitmapFactory了,通过各种decodeXXX()就可以从不同渠道获得Bitmap对象。
书中对于责任链模式选取的例子非常有代表性,那就是Android的触摸机制。
书中介绍观察者模式使用的是ListView的Adapter为例子,我之前知道Adapter属于适配器模式,不知道这里还有观察者模式的身影。
我觉得,模板方法模式的使用场景也是一句话:流程确定,具体实现细节由子类完成。
这里要关注一下『流程』这个关键字,随便拿一个抽象类,都符合”具体实现细节由子类完成”的要求,关键就在于是否有流程,有了流程,就叫模板方法模式,没有流程,就是抽象类的实现。
书中讲这个模式用的是AsyncTask,各个方法之间的执行符合流程,具体实现由我们完成,非常经典。
装饰器模式关注于在一个对象上动态的添加方法,而代理模式关注于控制对对象的访问。
代理模式,代理类可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。而当我们使用装饰器模式的时候,通常的做法是将原始对象作为一个参数传给装饰者的构造器。
5.如何将SQLite数据库(dictionary.db文件)与apk文件一起发布? 
可以将dictionary.db文件复制到Eclipse Android工程中的res raw目录中。所有在res raw目录中的文件不会被压缩,这样可以直接提取该目录中的文件。可以将dictionary.db文件复制到res raw目录中。
6.事件分发主要分为两部分:view的事件分发和viewgroup的事件分发。
1.view的事件分发:  dsipatchTouchEvent 方法:事件分发 和 onTouchEvent方法:事件消费。
2.viewGroup的事件分发:  dsipatchTouchEvent 方法:事件分发 和 onTouchEvent方法:事件消费  onInterceptTouchevent:事件拦截。
View和ViewGroup的事件分发和处理的总流程,当我们手指触摸屏幕时,
事件会传入到我们编写的布局文件的根布局上,如上面我们自定义的MyLinearLayout中,
寻找MyLinearLayout的dispatchTouchEvent方法进行事件分发,由于LinearLayout中本身没有该方法,
就往上寻找到其父类ViewGroup的dispatchTouchEvent方法,往下分发前查看该ViewGroup的
onInterceptTouchEvent方法判断是否需要拦截掉该事件,如果不拦截遍历其子ViewGroup或子View,
直到碰到该往下分发过程中被某个ViewGroup拦截掉,或者最后分发到手指按下的最里面的View,
然后按照View的事件处理流程处理该事件。在ViewGroup事件分发过程中,会根据子View或者ViewGroup的
dispatchTouchEvent方法的返回值决定是否继续遍历分发下去。
7Android屏幕适配:
适配的最多的3个分辨率:1280*720,1920*1080,800*480。
解决方案:
1.支持各种屏幕尺寸:
    1.使用match_parent,wrap_content,weight。
    2.禁用绝对布局。
    3.使用限定符。
        1.尺寸限定符。
        2.使用最小宽度限定符。
        3.使用布局别名。
        4.使用屏幕方向限定符。
        5.使用自动拉伸图9.png。
2.支持各种屏幕密度    
    1.使用费密度制约像素。
    2.提供备用位图。
3.实施自适应用户界面流程。
对不同大小的屏幕提供不同的常用单位大小,对不同的分辨率提供不同的尺寸资源文件。
发布了24 篇原创文章 · 获赞 131 · 访问量 8967

猜你喜欢

转载自blog.csdn.net/qq_20798591/article/details/52957870