• 安卓Java面试题21-30


    🔥  21、AsyncTask使用在哪些场景?它的缺陷是什么?如何解决?🔥

    AsyncTask 运用的场景就是我们需要进行一些耗时的操作,耗时操作完成后更新主线程,或者在操作过程中对主线程的UI进行更新。

    缺陷:

    AsyncTask中维护着一个长度为128的线程池,同时可以执行5个工作线程,还有一个缓冲队列,当线程池中已有128个线程,缓冲队列已满时,如果 此时向线程提交任务,将会抛出RejectedExecutionException。

    解决:由一个控制线程来处理AsyncTask的调用判断线程池是否满了,如果满了则线程睡眠否则请求AsyncTask继续处理。

    🔥  22、Android系统assest文件夹里放文件,对于文件的大小有没有限制?🔥

    assets目录更像一个附录类型的目录,Android不会为这个目录中的文件生成ID并保存在R类当中,因此它与Android中的一些类和方法兼容度更低。

     同时,由于你需要一个字符串路径来获取这个目录下的文件描述符,访问的速度会更慢。但是把一些文件放在这个目录下会使一些操作更加方便,

     比方说拷贝一个数据库文件到系统内存中。要注意的是,你无法在Android XML文件中引用到assets目录下的文件,只能通过AssetManager来访问这些文件。

     数据库文件和游戏数据等放在这个目录下是比较合适的。

    另外,网上关于assets和raw的资料都千篇一律了,因此关于这两者中单个文件大小不能超过1M的**错误**描述也在传播,即如果读取超过1M的文件会报"Data exceeds UNCOMPRESS_DATA_MAX (1314625 vs 1048576)"的
    IOException,还引申出种种解决方案。

    个人认为不应该有这样的限制,为了验证这个说法写了个Demo,发现将近5M的压缩包在assets和raw中都能正常访问,因此在这里纠正一下,理论上只要打包不超过Android APK 50M大小的限制都是没有问题的。

    当然了,不排除是Android很早期的时候因为设备硬件原因aapt在编译的时候对这两个文件夹大小做出了限制,如果是这样,较新版的ADT应该不会出现这种情况。 

     🔥  23、启动一个程序可以主界面点击图标进入,也可以从一个程序中跳转过去,二者有什么区别?🔥

    是因为启动程序(主界面也是一个app),发现了在这个程序中存在一个设置为的activity,所以这个launcher会把icon提出来,放在主界面上。

     当用户点击icon的时候,发出一个Intent:
    Intent intent = mActivity.getPackageManager().getLaunchIntentForPackage(packageName);
    mActivity.startActivity(intent);
    跳过去可以跳到任意允许的页面,如一个程序可以下载,那么真正下载的页面可能不是首页(也有可能是首页),这时还是构造一个Intent,startActivity.
    这个intent中的action可能有多种view,download都有可能。

    系统会根据第三方程序向系统注册的功能,为你的Intent选择可以打开的程序或者页面。所以唯一的一点
    不同的是从icon的点击启动的intent的action是相对单一的,从程序中跳转或者启动可能样式更多一些。本质是相同的。

     🔥 24、Activity程序之间的亲和性的理解?🔥

    1、默认情况下一个应用的所有Activity都是具有相同的affinity,都是从application中继承,application的affinity默认就是manifest的包名。

     2、affinity对Activity来说,就像是身份证一样,可以告诉所在的Task,自己属于其中的一员。

     3、应用场合:
    a:根据affinity重新为Activity选择合适的宿主Task;
    b:与allowTaskReparenting属性配合;
    c:启动Activity使用Intent设置了FLAG_ACTIVITY_NEW_TASK标记。

     🔥 25、同一个程序不同的Activity是否可以放在不同的Task任务栈中?🔥

    可以放在不同的Task中。需要为不同的activity设置不同的affinity属性,启动activity的Intent需要包含FLAG_ACTIVITY_NEW_TASK标记。

    🔥  26、横竖屏切换时候Activity的生命周期?🔥

    1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次

    2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次

    3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法 

    🔥27、Dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念?🔥 

    Android 运行环境主要指的虚拟机技术——Dalvik。

    Android中的所有Java程序都是运行在Dalvik VM上的。

    Android上的每个程序都有自己的线程,DVM只执行.dex的Dalvik executable 文件。

    每个Android应用在底层都对应有一个独立的DVM实例并在其解释下执行。

    虽然DVM也是用Java编程语言,Dalvik虚拟机和一般JAVA虚拟机(Java VM)并不兼容,他们两个的区别是JVM标准执行的是.class的字节码(bytecode ),而是DVM执行的是其专有的(.dex)执行文件。

    在编译过程中,Java把类编译成一个或多个.class byte code 文件,然后打包到jar中,JVM会从中jar文件中获得相应的.class文件和JRE字节码。

    Android VM虽然也是是用Java语言进行编程, Java程序通过编译后,还需要通过SDK中的dex工具转化成.dex格式,DVM再从其中读取指令和数据。

     每一个应用程序即一个进程(Linux的一个Process)。

    二者最大的区别在于Java VM是以基于栈的虚拟机(Stack-based),而Dalvik是基于寄存器的虚拟机(Register-based)。

    显然,后者最大的好处在于可以根据硬件实现更大的优化,这更适合移动设备的特点。

     DVM非常适合在移动终端上使用,与PC相比,它不需要很快的CPU和大量的内存空间. Google的测算显示,64MB的内存已经能让系统正常运转了。

    其中24MB被用于底层系统的初始化和启动。

    另外20MB被用于启动高层服务。

    DVM有如下特征:
    •使用专有的.dex格式。

    •原因是Java类文件在编译过后,会产生至少一个.class文件包含大量陈余信息,dex文件格式会把所有的.class文件内容整合到一个.dex文件中。即减少了整体文件的尺寸和IO操作,也提高了类的查找速度。

    •增加了对新的操作码的支持
    •文件结构尽量简洁,使用等长的指令,借以提高解析速度。
    •尽量扩大只读结构的大小,借以提高跨进程的数据共享。

    •dex的优化,dex文件的结构是紧凑的,但是如果想提高运行时的性能,就需要对dex文件进行进一步的优化。

     dex的优化针对以下几个方面:

    •验证dex文件中的所有类
    •对一些特定的类和方法里面的操作码进行优化
    •调整所有的字节序(Little_endian)和对齐结构中的每一个域
    •基于寄存器,基于寄存器的虚拟机虽然比基于堆栈的虚拟机在硬件,通用性上要差一些,但是它的代码执行效率去更好
    •每一个Android应用都运行在它自己的DVM实例中,每一个DVM实例都是一个独立的进程空间。所有的Android应用的线程都对应一个Linux线程,DVM因此可以更多地依赖操作系统的线程调度和管理机制。不同的应用在不同的进程空间里运行,不同的应用都是用不同的Linux用户来运行以最大程度地保户应用程序的安全性和独立性

    小结:DVM指 dalivk 的虚拟机。每一个 Android 应用程序都在它自己的进程中运行,都拥有一个独立的 Dalvik 虚拟机实例。而每一个 DVM 都是在 Linux 中的一个进程,所以说可以认为是同一个概念。

    每一个DVM都是在Linux 中的一个进程!

    🔥  28、如何理解Activity,View,Window三者之间的关系?🔥

    里先来个算是比较恰当的比喻来形容下它们的关系吧。

    Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图)LayoutInflater像剪刀,Xml配置像窗花图纸。

    1:Activity构造的时候会初始化一个Window,准确的说是PhoneWindow。

    2:这个PhoneWindow有一个“ViewRoot”,这个“ViewRoot”是一个View或者说ViewGroup,是最初始的根视图。 

     3:“ViewRoot”通过addView方法来一个个的添加View。比如TextView,Button等

    4:这些View的事件监听,是由WindowManagerService来接受消息,并且回调Activity函数。比如onClickListener,onKeyDown等。 

     🔥29、Activity的几种LaunchMode及使用场景?🔥

    standard 模式
    这是默认模式,每次激活Activity时都会创建Activity实例,并放入任务栈中。

    使用场景:大多数Activity。

     singleTop 模式
    如果在任务的栈顶正好存在该Activity的实例,就重用该实例( 会调用实例的 onNewIntent() ),否则就会创建新的实例并放入栈顶,即使栈中已经存在该Activity的实例,只要不在栈顶,都会创建新的实例。使用场景如新闻类或者阅读类App的内容页面。

     singleTask 模式
    如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的 onNewIntent() )。

    重用时,会让该实例回到栈顶,因此在它上面的实例将会被移出栈。

    如果栈中不存在该实例,将会创建新的实例放入栈中。

    使用场景如浏览器的主界面。

    不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。

     singleInstance 模式
    在一个新栈中创建该Activity的实例,并让多个应用共享该栈中的该Activity实例。

    一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例( 会调用实例的 onNewIntent() )。

    其效果相当于多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。

    使用场景如闹铃提醒,将闹铃提醒与闹铃设置分离。

    singleInstance不要用于中间页面,如果用于中间页面,跳转会有问题,比如:A -> B (singleInstance) -> C,完全退出后,在此启动,首先打开的是B。

     🔥 30、 Android 中如何捕获未捕获的异常?🔥

    1. public class CrashHandler implements Thread.UncaughtExceptionHandler {
    2. private static CrashHandler instance = null;
    3. public static synchronized CrashHandler getInstance(){
    4. if(instance == null){
    5. instance = new CrashHandler();
    6. }
    7. return instance;
    8. }
    9. public void init(Context context){
    10. Thread.setDefaultUncaughtExceptionHandler(this);
    11. }
    12. @Override
    13. public void uncaughtException(Thread thread, Throwable ex) {
    14. StringBuilder stringBuilder = new StringBuilder();
    15. stringBuilder.append("Thread:");
    16. stringBuilder.append(thread.toString());
    17. stringBuilder.append(" ");
    18. stringBuilder.append(ex);
    19. TraceLog.i(stringBuilder.toString());
    20. TraceLog.printCallStatck(ex);
    21. }
    22. }
  • 相关阅读:
    java8 LocalDateTime
    idea怎么连接redis
    微信小程序查看官方样式及修改checkbox样式为圆圈
    【Linux网络编程】多进程编程
    嵌入式 Linux 入门(六、Shell 脚本编程下:Shell 脚本语法)
    c# Json转C#实体
    音视频开发—音频相关概念:数模转换、PCM数据与WAV文件详解
    力扣.面试题 04.06. 后继者(java 树的中序遍历)
    公网环境下使用VNC远程连接Ubuntu系统桌面
    Kubernetes 集群环境搭建
  • 原文地址:https://blog.csdn.net/u013491829/article/details/136550545