关闭

android面试中的一些问题修正

标签: andorid面试
294人阅读 评论(0) 收藏 举报
分类:

也不是多大的问题,但是常用却容易混淆,都网络资源,整合了自己的语言,不明白的话 请参见原文

1.activity横竖屏切换生命周期

      经实验,我认为网上大多数说法错误:

    我的正确认知:1.横变竖,竖变橫activity都会被销毁一次创建一次(网上错误:橫变竖2次)

                                2.设置不变屏

                                     activity中设置

android:screenOrientation="portrait"//竖屏

android:screenOrientation="<span style="font-size:14px;"><span style="font-family:verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif;line-height: 24px; background-color: rgb(255, 255, 255);">landscape</span></span>"// 横屏

                                3.屏幕旋转时不重新走生命周期在mainfest中,三个都要配置否则可能出现无效的结果

android:configChanges="keyboardHidden|orientation|screenSize"

                                  就只会走方法一次

onConfigurationChanged(Configuration newConfig)

2.数据库耗时的问题

    数据库需要开关流。开关事物。如果把很多系数据操作,放入一个事物中,可以只开关一次io流,缩短时间

3.String和StringBuffer,StringBuilder的区别

  String是final类,不可追加

后两者可以追加,StringBuffer线程安全(单线程或者说通过代码保护),可追加,较快  

                                StringBuilder线程不安全(多线程),可追加,很快

4.android更新ui的主要方法(我觉得就是在主线程更新,或者说子线程如何更新ui,但是就是这么问)

1.利用Looper更新UI界面(就是handler)

2.AsyncTask利用线程任务异步更新UI界面

3.利用Runnable更新UI界面比如:Activity.runOnUiThread() 方法

5.堆和栈的区别

堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。(int a= 3 ;int b = 3; a和b指向一致)

6.线程的5种状态

新建-就绪状态(无xpu)-阻塞状态(有cpu  a.seelp  b.被耗时阻塞如io读取  c.进入同步锁代码单被别人占用 d.等待某个触发条件)-运行状态(有cpu)-死亡状态

7.面向对象的三大特征:五大原则;

封装,继承,多态

五大基本原则

单一职责原则SRP(Single Responsibility Principle)
是指一个类的功能要单一,不能包罗万象。如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起来。

开放封闭原则OCP(Open-Close Principle) 
一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。比如:一个网络模块,原来只服务端功能,而现在要加入客户端功能,
那么应当在不用修改服务端功能代码的前提下,就能够增加客户端功能的实现代码,这要求在设计之初,就应当将服务端和客户端分开,公共部分抽象出来。

替换原则(the Liskov Substitution Principle LSP) 
子类应当可以替换父类并出现在父类能够出现的任何地方。比如:公司搞年度晚会,所有员工可以参加抽奖,那么不管是老员工还是新员工,
也不管是总部员工还是外派员工,都应当可以参加抽奖,否则这公司就不和谐了。

依赖原则(the Dependency Inversion Principle DIP) 具体依赖抽象,上层依赖下层。假设B是较A低的模块,但B需要使用到A的功能,
这个时候,B不应当直接使用A中的具体类: 而应当由B定义一抽象接口,并由A来实现这个抽象接口,B只使用这个抽象接口:这样就达到
了依赖倒置的目的,B也解除了对A的依赖,反过来是A依赖于B定义的抽象接口。通过上层模块难以避免依赖下层模块,假如B也直接依赖A的实现,那么就可能造成循环依赖。一个常见的问题就是编译A模块时需要直接包含到B模块的cpp文件,而编译B时同样要直接包含到A的cpp文件。

接口分离原则(the Interface Segregation Principle ISP) 
模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来

8.view刷新自己的方法

一组是invalidate                                主线程调用

另一组是postInvalidate                    子线程调用

9.线程同步的方法

1.同步方法
2.同步代码块 

3.使用特殊域变量(volatile)实现线程同步  她是用来修饰变量的

4.a.使用重入锁实现线程同步ReentrantLock() :   创建一个ReentrantLock实例lock        lock. lock() : 获得锁         lock.unlock() : 释放锁

    b.ReentrantLock()还有一个可以创建公平锁的构造方法,但由于能大幅度降低程序运行效率,不推荐使用

10.int和Integer的区别

1。Ingeter是int的包装类

2.int的初值为0,Ingeter的初值为null。

3.int定义的是变量,Integer定义的是对象。 前者定义的值是存在栈中,后者在堆中

11.嵌入式

12.单元测试

13.跨进程通信

 http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f7636d918d027fa3c215cc7902155a66e1b827201019d0c6776403ad5e5c9daa702d691765eadb9e871981edd27574de3034010bf63705a713b8bb4732b051875b99b86996ad873484afa2c4af5344bb55127bf0e7fa2c1767c07886162692a1&p=882a964fd18c13e007b8c7710f6490&newp=9b3bd3109c904ead08e297740a0083231610db2151d7d0156b82c825d7331b001c3bbfb423231006d8cf7b6602ae495feaf436783c0821a3dda5c91d9fb4c57479&user=baidu&fm=sc&query=android+%BD%F8%B3%CC%BC%E4%B5%C4%CD%A8%D0%C5&qid=ad5bdbd8000408f5&p1=1

4种方式 四个组件 活动(电话本)  广播 服务  内容提供者

14.intent 和intentfilter  

http://blog.csdn.net/cnnumen/article/details/8464786

http://www.cnblogs.com/liushengjie/archive/2012/08/30/2663066.html

intent是在代码内部实现的,intentfilter通常是在mainfest里配置实现的


intent可以设置ComponentName 或者直接在构造方法里填入 new Intent(A.this,B.class);设置显式跳转

而隐式Intent则通过Intent中的action, category, data,查找mainfest中activity中的intenfilter的action, category, data来匹配跳转 优先级:action->data->category


常用action                           intent最多只能定义1个action, 而filter可以定义1个或多个action. 隐式跳转 intent定义的必须满足

ACTION_CALL--目标组件为activity, 代表拨号动作;
ACTION_EDIT--目标组件为activity, 代表向用户显示数据以供其编辑的动作;
ACTION_MAIN--目标组件为activity, 表示作为task中的初始activity启动;
ACTION_BATTERY_LOW--目标组件为broadcastReceiver, 提醒手机电量过低;
ACTION_SCREEN_ON--目标组件为broadcast, 表示开启屏幕.


Category属性                    intent可以任意多个category, filter也可以任意个category.                   隐式跳转 intent定义的多个必须满足
category属性也是一个字符串, 用于指定一些目标组件需要满足的额外条件. Intent对象中可以包含任意多个category属性. Intent类也预定义了一些category常量, 开发者也可以自定义category属性.
Intent类的addCategory()方法为Intent添加Category属性, getCategories()方法用于获取Intent中封装的所有category.
以下是Intent类中预定义的部分category:
CATEGORY_HOME--表示目标activity必须是一个显示home screen的activity;                           隐式跳转 intent定义的必须满足
CATEGORY_LAUNCHER--表示目标activity可以作为task栈中的初始activity, 常与ACTION_MAIN配合使用;
CATEGORY_GADGET--表示目标activity可以被作为另一个activity的一部分嵌入.


Intent的Data属性             intent最多只能定义1个data, filter则可以定义多个data.  
data属性指定所操作数据的URI. data经常与action配合使用, 如果action为ACTION_EDIT, data的值应该指明被编辑文档的URI; 如果
action为ACTION_CALL, data的值应该是一个以"tel:"开头并在其后附加号码的URI; 如果action为ACTION_VIEW, data的值应该是一个以"http: "开头并在其后附加网址的URI...
Intent类的setData()方法用于设置data属性, setType()方法用于设置data的MIME类型, setDataAndType()方法可以同时设定两者. 可以通过getData()方法获取data属性的值, 通过getType()方法获取data的MIME类型.



15.activity设置为窗口模式http://blog.csdn.net/zuo_0625/article/details/51325032

1.在AndroidManifest.xml清单配置文件中修改当前Activity的theme属性 可以在application中设置  也可以在activity‘中设置

    android:theme="@style/Theme.AppCompat.Light.Dialog"  

2.自定义style设置

    <resources>  
      
        <!-- Base application theme. -->  
        <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">  
            <!-- Customize your theme here. -->  
            <item name="colorPrimary">@color/colorPrimary</item>  
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>  
            <item name="colorAccent">@color/colorAccent</item>  
        </style>  
      
        <style name="Theme.FloatActivity" parent="Theme.AppCompat.Light.Dialog">  
            <item name="android:windowBackground">@drawable/float_box</item>  
        </style>  
    </resources>  

自定义drawable中的

 shape

    <?xml version="1.0" encoding="utf-8"?>  
    <shape xmlns:android="http://schemas.android.com/apk/res/android">  
      
        <solid android:color="@color/colorAccent"/>  
        <stroke android:width="3dp" android:color="#000000"/>  
        <corners android:radius="5dp"/>  
        <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp"/>  
    </shape>  



16.输入框布局上移 http://www.cnblogs.com/CaptainLin/p/3835724.html

1.在代码中设置

在你的activity中的oncreate中setContentView之前写上这个代码getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

2.在mainfest中配置

在项目的AndroidManifest.xml文件中界面对应的<activity>里加入android:windowSoftInputMode="stateVisible|adjustResize",这样会让屏幕整体上移。如果加上的是
                android:windowSoftInputMode="adjustPan"这样键盘就会覆盖屏幕。

3.在xml中配置

把顶级的layout替换成ScrollView,或者说在顶级的Layout上面再加一层ScrollView的封装。这样就会把软键盘和输入框一起滚动了,软键盘会一直处于底部

17.Thread.Runnable的区别

Thread

(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。
采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。

18.Service的使用,如何避免Service被杀死

service2启动方式 ,startService(intent) bindservice(intent)

  前者会一直运行,直到 stopService(intent)或者在服务内部stopSelf(),stopSelf(int );   stopSelf(int)的意思是处理完所有的satrtService后才停止服务, 参数是startService的次数

  后者与,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止onUnbind()方法解除调用者与服务解除


服务的进程级别较高 ,会优先一运行
1. 如果service正在调用onCreate,onStartCommand或者onDestory方法,那么用于当前service的进程则变为前台进程以避免被killed。
2. 如果当前service已经被启动(start),拥有它的进程则比那些用户可见的进程优先级低一些,但是比那些不可见的进程更重要,这就意味着service一般不会被killed.
3. 如果客户端已经连接到service (bindService),那么拥有Service的进程则拥有最高的优先级,可以认为service是可见的。
4. 如果service可以使用startForeground(int, Notification)方法来将service设置为前台状态,那么系统就认为是对用户可见的,并不会在内存不足时killed。


保证不被杀死

第一种:

StartCommond几个常量参数简介:

1、START_STICKY

在运行onStartCommand后service进程被kill后,那将保留在开始状态,但是不保留那些传入的intent。不久后service就会再次尝试重新创建,因为保留在开始状态,在创建     service后将保证调用onstartCommand。如果没有传递任何开始命令给service,那将获取到null的intent。

2、START_NOT_STICKY

在运行onStartCommand后service进程被kill后,并且没有新的intent传递给它。Service将移出开始状态,并且直到新的明显的方法(startService)调用才重新创建。因为如果没有传递任何未决定的intent那么service是不会启动,也就是期间onstartCommand不会接收到任何null的intent。

3、START_REDELIVER_INTENT

在运行onStartCommand后service进程被kill后,系统将会再次启动service,并传入最后一个intent给onstartCommand。直到调用stopSelf(int)才停止传递intent。如果在被kill后还有未处理好的intent,那被kill后服务还是会自动启动。因此onstartCommand不会接收到任何null的intent。

@Override  
public int onStartCommand(Intent intent, int flags, int startId) {  
    flags = START_STICKY;  
    return super.onStartCommand(intent, flags, startId);  
} 

结果手动返回START_STICKY,亲测当service因内存不足被kill,当内存又有的时候,service又被重新创建,比较不错,但是不能保证任何情况下都被重建,比如进程被干掉了....

第二种:

提升service优先级

在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = "1000"这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时适用于广播。

<service  
    android:name="com.dbjtech.acbxt.waiqin.UploadService"  
    android:enabled="true" >  
    <intent-filter android:priority="1000" >  
        <action android:name="com.dbjtech.myservice" />  
   </intent-filter>  
</service>  

结论:目前看来,priority这个属性貌似只适用于broadcast,对于Service来说可能无效

第三种

Android中的进程是托管的,当系统进程空间紧张的时候,会依照优先级自动进行进程的回收。Android将进程分为6个等级,它们按优先级顺序由高到低依次是:

   1.前台进程( FOREGROUND_APP)
   2.可视进程(VISIBLE_APP )
   3. 次要服务进程(SECONDARY_SERVER )
   4.后台进程 (HIDDEN_APP)
   5.内容供应节点(CONTENT_PROVIDER)
   6.空进程(EMPTY_APP)

当service运行在低内存的环境时,将会kill掉一些存在的进程。因此进程的优先级将会很重要,可以使用startForeground将service放到前台状态。这样在低内存时被kill的几率会低一些。

第四种

onDestroy方法里重启service

service +broadcast  方式,就是当service走ondestory的时候,发送一个自定义的广播,当收到广播的时候,重新启动service;

<receiver android:name="com.dbjtech.acbxt.waiqin.BootReceiver" >  
    <intent-filter>  
        <action android:name="android.intent.action.BOOT_COMPLETED" />  
        <action android:name="android.intent.action.USER_PRESENT" />  
        <action android:name="com.dbjtech.waiqin.destroy" />//这个就是自定义的action  
   </intent-filter>  
</receiver>  

在onDestroy时:

    @Override  
    public void onDestroy() {  
        stopForeground(true);  
        Intent intent = new Intent("com.dbjtech.waiqin.destroy");  
        sendBroadcast(intent);  
        super.onDestroy();  
    }  

在BootReceiver里

    public class BootReceiver extends BroadcastReceiver {  
      
        @Override  
        public void onReceive(Context context, Intent intent) {  
            if (intent.getAction().equals("com.dbjtech.waiqin.destroy")) {  
                //TODO  
                //在这里写重新启动service的相关操作  
                    startUploadService(context);  
            }  
      
        }  
      
    }  


或者不用广播

也可以直接在onDestroy()里startService

    @Override  
    public void onDestroy() {  
      
         Intent sevice = new Intent(this, MainService.class);  
         this.startService(sevice);  
      
        super.onDestroy();  
    }  

第五种

Application加上Persistent属性
看Android的文档知道,当进程长期不活动,或系统需要资源时,会自动清理门户,杀死一些Service,和不可见的Activity等所在的进程。但是如果某个进程不想被杀死(如数据缓存进程,或状态监控进程,或远程服务进程),可以这么做:

    <application  
        android:name="com.test.Application"  
        android:allowBackup="true"  
        android:icon="@drawable/ic_launcher"  
        android:label="@string/app_name"  
       <span style="color:#ff0000;"> android:persistent="true"</span>  
        android:theme="@style/AppTheme" >  
    </application>  

第六种

开两个服务,互相监视


19.内存的管理

尽可能少的使用服务,或者使用Intentservice,保证服务的准确性

使用优化过的代码代替存储hashmap用 SparseArray替代

避免枚举

避免注解

第三方库要小心

使用ProGuard筛除无用代码


bitmap即使释放资源  查询数据库及时关闭  避免静态 避免全局  adapter优化 context尽量 application的context


线程的优化:

ui的优化:


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:14329次
    • 积分:394
    • 等级:
    • 排名:千里之外
    • 原创:21篇
    • 转载:16篇
    • 译文:1篇
    • 评论:1条