美文网首页
Android 面试题之四大组件相关

Android 面试题之四大组件相关

作者: 侯蛋蛋_ | 来源:发表于2018-01-13 08:58 被阅读0次

    如何判断当前BroadcastReceiver接受到的是有序广播还是无序广播

    在BroadcastReceiver类中onReceiver()方法中,可以调用boolean b=isOrderedBroadcast();该方法是BroadcastReceiver类中提供的方法,用于高速我们当前的接收到的广播是否为有序广播

    在manifest和代码中如何注册和使用BroadcastReceiver

    在清单文件中注册广播接收者称为静态注册,在代码中注册称为动态注册。

    静态注册的广播接收者只要app在系统中运行则一直可以接收到广播消息,动态注册的广播接收者当注册的Activity或者Service销毁了那么就接收不到广播了。

    • 静态注册:在清单文件中进行如下配置:
    <receiver android:name=".BroadcastReceiver1" >
    <intent-filter>
    <action android:name="android.intent.action.CALL" >
    </action>
    </intent-filter>
    </receiver>
    
    • 动态态注册:在代码中进行如下注册
    receiver = new BroadcastReceiver(); 
    IntentFilter intentFilter = new IntentFilter(); 
    intentFilter.addAction(CALL_ACTION); 
    context.registerReceiver(receiver, intentFilter);
    

    Service系列问题

    Service本地服务及生命周期详解

    1.1 注册Service需要注意什么

    Service还是运行在主线程当中的,所以如果需要执行一些复杂的逻辑操作,最好在服务的内部手动创建子线程进行处理,否则会出现UI线程被阻塞的问题

    1.2 Service与Activity怎么实现通信(不要死记硬背,结合文章)

    相关文章

    Service和Activity的相互通信

    • 方法一:

        1. 添加一个继承Binder的内部类,并添加相应的逻辑方法
        1. 重写Service的onBind方法,返回我们刚刚定义的那个内部类实例
        1. 重写ServiceConnection,onServiceConnected时调用逻辑方法 绑定服务
    • 方法二

      • 通过接口Iservice调用Service方法,使用接口调用service和直接调用其实本质都是一样的,只不过多了借口一个步骤

    1.3 介绍源码中Binder机制(了解)

    面试问到这个,其实就是让你说一下binder是干什么的,Service Manager是如何成为一个守护进程的

    Binder机制

    1.4 IntentService与Service的区别(intentservice的优点)

    IntentService是Service的子类,是一个异步的,会自动停止的服务,很好解决了传统的Service中处理完耗时操作忘记停止并销毁Service的问题

    • 会创建独立的worker线程来处理所有的Intent请求;
    • 会创建独立的worker线程来处理onHandleIntent()方法实现的代码,无需处理多线程问题;
    • 所有请求处理完成后,IntentService会自动停止,无需调用stopSelf()方法停止Service;
    • 为Service的onBind()提供默认实现,返回null;
    • 为Service的onStartCommand提供默认实现,将请求Intent添加到队列中;
    • IntentService不会阻塞UI线程,而普通Serveice会导致ANR异常
    • Intentservice若未执行完成上一次的任务,将不会新开一个线程,是等待之前的任务完成后,再执行新的任务,等任务完成后再次调用stopSelf()

    1.5 Service 是否在 main thread 中执行, service 里面是否 能执行耗时的操作?

    默认情况,如果没有显示的指 service 所运行的进程, Service 和 activity 是运 行在当前 app 所在进程的 main thread(UI 主线程)里面。

    service 里面不能执行耗时的操作(网络请求,拷贝数据库,大文件 )

    特殊情况 ,可以在清单文件配置 service 执行所在的进程 ,让 service 在另 外的进程中执行

    <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" >
    </service>
    

    1.6 Service的生命周期

    Service 有绑定模式和非绑定模式,以及这两种模式的混合使用方式。不同 的使用方法生命周期方法也不同。

    • 非绑定模式:当第一次调用 startService 的时候执行的方法依次为 onCreate()、onStartCommand(),当 Service 关闭的时候调用 onDestory 方 法。

    • 绑定模式:第一次 bindService()的时候,执行的方法为 onCreate()、 onBind()解除绑定的时候会执行 onUnbind()、onDestory()。

    上面的两种生命周期是在相对单纯的模式下的情形。我们在开发的过程中还 必须注意 Service 实例只会有一个,也就是说如果当前要启动的 Service 已经存 在了那么就不会再次创建该 Service 当然也不会调用 onCreate()方法。

    一个 Service 可以被多个客户进行绑定,只有所有的绑定对象都执行了

    onBind()方法后该 Service 才会销毁,不过如果有一个客户执行了 onStart() 方法,那么这个时候如果所有的 bind 客户都执行了 unBind()该 Service 也不会 销毁。

    Service 的生命周期图如下所示,帮助大家记忆。

    只使用startService启动服务的生命周期

    只使用BindService绑定服务的生命周期

    同时使用startService()启动服务、BindService()绑定服务的生命周期

    1.7 Activity、Intent、Service 是什么关系(了解)

    他们都是 Android 开发中使用频率最高的类。其中 Activity 和 Service 都是 Android 四大组件之一。他俩都是 Context 类的子类 ContextWrapper 的子类, 因此他俩可以算是兄弟关系吧。不过兄弟俩各有各自的本领,Activity 负责用户 界面的显示和交互,Service 负责后台任务的处理。Activity 和 Service 之间可 以通过 Intent 传递数据,因此可以把 Intent 看作是通信使者。

    1.8 Service 和 Activity 在同一个线程吗?

    对于同一 app 来说默认情况下是在同一个线程中的,main Thread (UI Thread)。

    1.9 在 service 的生命周期方法 onstartConmand()可不可以执行网络操作?如何在 service 中执行网络操作?(在service如何执行耗时操作)

    可以直接在 Service 中执行网络操作,在 onStartCommand()方法中可以执行网络操作

    如果需要在服务中进行耗时操作,可以选择IntentService, IntentService是Service的子类,用来处理异步请求。

    IntentService在onCreate()方法中通过HandlerThread单独开启一个线程来处理Intent请求对象所对应的任务,这样可以避免事务处理阻塞主线程。

    onHandleIntent()函数针对Intent的不同进行不同的事务处理就可以,执行完一个Intent请求对象所对应的工作之后,如果没有新的Intent请求达到,则自动停止Service; 否则ServiceHandler会取得下一个Intent请求
    传入该函数来处理其所对应的任务。

    2.0 如何提高service的优先级? (理解,说出两三条就很nB了)

    参考文章

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

    • 2、在onStartCommand里面调用 startForeground()方法把Service提升为前台进程级别,然后再onDestroy里面要记得调用stopForeground ()方法。

    • 3、onStartCommand方法,手动返回START_STICKY。

    • 4、 在onDestroy方法里发广播重启service。
      service +broadcast 方式,就是当service走ondestory的时候,发送一个自定义的广播,当收到广播的时候,重新启动service。(第三方应用或是在setting里-应用-强制停止时,APP进程就直接被干掉了,onDestroy方法都进不来,所以无法保证会执行)

    • 5、监听系统广播判断Service状态。
      通过系统的一些广播,比如:手机重启、界面唤醒、应用状态改变等等监听并捕获到,然后判断我们的Service是否还存活。

    • 6、Application加上Persistent属性。

    2.1 Service 的 onStartCommand 方法有几种返回值?各代表什么意思?

    有四种返回值,不同值代表的意思如下:

    • START_STICKY:如果 service 进程被 kill 掉,保留 service 的状态为开始状态,但不保留递送的 intent 对象。随 后系统会尝试重新创建 service,由于服务状态为开始状态,所以创建服务后一定会调用 onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到 service,那么参数 Intent 将为 null。
    • START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完 onStartCommand 后,服务被异常 kill 掉,系统不会自动重启该服务。
    • START_REDELIVER_INTENT:重传 Intent。使用这个返回值时,如果在执行完 onStartCommand 后,服务被异 常 kill 掉,系统会自动重启该服务,并将 Intent 的值传入。
    • START_STICKY_COMPATIBILITY: START_STICKY 的兼容版本,但不保证服务被 kill 后一定能重启。

    2.2 Service 的 onRebind(Intent)方法在什么情况下会执行?

    如果在 onUnbind()方法返回 true 的情况下会执行,否则不执行。

    2.3 Activity 调用 Service 中的方法都有哪些方式?

    • Binder:
      通过 Binder 接口的形式实现,当 Activity 绑定 Service 成功的时候 Activity 会在 ServiceConnection 的类 的 onServiceConnected()回调方法中获取到 Service 的 onBind()方法 return 过来的 Binder 的子类,然后通过对象调用方法。

    • Aidl:
      aidl 比较适合当客户端和服务端不在同一个应用下的场景。

    • Messenger:
      它引用了一个Handler对象,以便others能够向它发送消息(使用mMessenger.send(Message msg)方法)。该类允许跨进程间基于Message的通信(即两个进程间可以通过Message进行通信),在服务端使用Handler创建一个Messenger,客户端持有这个Messenger就可以与服务端通信了。一个Messeger不能同时双向发送,两个就就能双向发送了

    这里画了一个粗浅的图帮助大家理解。

    image.png

    1. Activity 系列问题

    1.1 请简要介绍Android的四大组件。(会说即可,不用死记硬背)

    • Activity:提供一个界面让用户点击和各种滑动操作
    • Service :可以在后台执行长时间运行操作而没有用户界面的应用组件
    • Broadcast Receiver :一种广泛运用在应用程序之间传输信息的机制,通过发送Intent来传送我们的数据
    • Content Provider :内容提供者,它是用在不同的应用程序之间共享数据时,可以把一个应用的数据提供给其他的应用使用。

    1.2 Android中Activity, Intent, Content Provider, Service各有什么区别。(说出他们是什么即可)

    • Activity:
    • Intent: 意图,描述应用想干什么。最重要的部分是动作和动作对应的数据。
    • Content Provider:
    • Service:

    1.3 Manifest.xml文件中主要包括哪些信息?

    • 1.manifest:根节点,描述了package中所有的内容。
    • 2.uses-permission:请求你的package正常运作所需赋予的安全许可。
    • 3.permission: 声明了安全许可来限制哪些程序能你package中的组件和功能。
    • 4.instrumentation:声明了用来测试此package或其他package指令组件的代码。
    • 5.application:包含package中application级别组件声明的根节点。
    • 6.activity:Activity是用来与用户交互的主要工具。
    • 7.receiver:IntentReceiver能使的application获得数据的改变或者发生的操作,即使它当前不在运行。
    • 8.service:Service是能在后台运行任意时间的组件。
    • 9.provider:ContentProvider是用来管理持久化数据并发布给其他应用程序使用的组件。

    1.4 绘制Activity生命周期流程图(Activity的生命周期)

    1.4 介绍下不同场景下Activity生命周期的变化过程

    • 启动Activity: onCreate()--->onStart()--->onResume(),Activity进入运行状态。
    • Activity退居后台: 当前Activity转到新的Activity界面或按Home键回到主屏: onPause()--->onStop(),进入停滞状态。
    • Activity返回前台: onRestart()--->onStart()--->onResume(),再次回到运行状态。
    • Activity退居后台,且系统内存不足, 系统会杀死这个后台状态的Activity,若再次回到这个Activity,则会走onCreate()-->onStart()--->onResume()
    • 锁定屏与解锁屏幕 只会调用onPause(),而不会调用onStop方法,开屏后则调用onResume()

    1.5 内存不足时系统会杀掉后台的Activity,若需要进行一些临时状态的保存,在哪个方法进行?

    Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不同于 onCreate()、onPause()等生命周期方法,它们并不一定会被触发。

    答:onSaveInstanceState() 方法,当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity,onSaveInstanceState() 会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。除非该activity是被用户主动销毁的,通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。

    1.6 onSaveInstanceState()被执行的场景有哪些:

    系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,因此系统都会调用onSaveInstanceState(),让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则

      1. 当用户按下HOME键时
      1. 长按HOME键,选择运行其他的程序时
      1. 锁屏时
      1. 从activity A中启动一个新的activity时
      1. 屏幕方向切换时

    1.7 两个 Activity 之间跳转时必然会执行的是哪几个方法?

    一般情况下比如说有两个 activity,分别叫 A,B,当在 A 里面激活 B 组件的时候, A 会调用 onPause()方法,然后 B 调用 onCreate() ,onStart(), onResume()。

    这个时候 B 覆盖了窗体, A 会调用 onStop()方法. 如果 B 是个透明的,或者 是对话框的样式, 就不会调用 A 的 onStop()方法。

    1.8 如何将一个 Activity 设置成窗口的样式?

    只需要给我们的 Activity 配置如下属性即可。
    android:theme="@android:style/Theme.Dialog"

    1.9如何退出 Activity?如何安全退出已调用多个 Activity 的 Application?(知道即可)

    • 1.通常情况用户退出一个 Activity 只需按返回键,我们写代码想退出 activity 直接调用 finish()方法就行。
    • 2.发送特定广播:

    在需要结束应用时,发送一个特定的广播,每个 Activity 收到广播后,关闭 即可。

    //给某个 activity 注册接受接受广播的意图 registerReceiver(receiver, filter)

    //如果过接受到的是 关闭 activity 的广播 activity finish()掉

    • 3.递归退出
      就调用 finish()方法 把当前的
      在打开新的 Activity 时使用 startActivityForResult,然后自己加标志,在 onActivityResult 中处理,递归关闭。
    • 4.其实 也可以通过 intent 的 flag 来实现 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)激活一个新的 activity。 此时如果该任务栈中已经有该 Activity,那么系统会把这个 Activity 上面的所有 Activity 干掉。其实相当于给 Activity 配置的启动模式为 SingleTop。
    • 5.记录打开的 Activity:
      每打开一个 Activity,就记录下来。在需要退出时,关闭每一个 Activity
    //伪代码
    List<Activity> lists ;// 在 application 全局的变量里面 lists = new ArrayList<Activity>();
    lists.add(this);
    for(Activity activity: lists)
    {
           activity.finish();
        }
    lists.remove(this); 
    

    2.0 Android 中的 Context, Activity,Appliction 有什么区别?

    • 相同:Activity 和 Application 都是 Context 的子类。
      Context 从字面上理解就是上下文的意思,在实际应用中它也确实是起到了管理 上下文环境中各个参数和变量的总用,方便我们可以简单的访问到各种资源。
    • 不同:维护的生命周期不同。Context 维护的是当前的 Activity 的生命周期, Application 维护的是整个项目的生命周期。使用 context 的时候,小心内存泄露,防止内存泄露,注意一下几个方面:

    2.1 Context 是什么?(理解)

    1、它描述的是一个应用程序环境的信息,即上下文。

    2、该类是一个抽象(abstract class)类,Android 提供了该抽象类的具体实 现类(ContextIml)。

    3、通过它我们可以获取应用程序的资源和类,也包括一些应用级别操作, 例如:启动一个 Activity,发送广播,接受 Intent,信息,等。

    附加一张Context继承关系图

    这里写图片描述

    2.2如何获取当前屏幕Activity的对象?

    使用ActivityLifecycleCallbacks

    传送地址:

    Android 如何获取当前Activity实例对象?

    2.3你知道onNewIntent吗?

    如果IntentActivity处于任务栈的顶端,也就是说之前打开过的Activity,现在处于onPause、onStop 状态的话,其他应用再发送Intent的话,执行顺序为:
    onNewIntent,onRestart,onStart,onResume。

    2.4 除了用Intent 去启动一个Activity,还有其他方法吗?

    使用adb shell am 命令

    am启动一个activity
    adb shell am start com.example.fuchenxuan/.MainActivity
    am发送一个广播,使用action
    adb shell am broadcast -a magcomm.action.TOUCH_LETTER

    2.5 Android Service与Activity之间通信的几种方式?

    • 通过Binder对象
      当Activity通过调用bindService(Intent service, ServiceConnection conn,int flags),得到一个Service的一个对象,通过这个对象我们可以直接访问Service中的方法。
    • 通过Broadcast Receiver(广播)的形式
    • EventBus

    2.6 如果新Activity是透明主题时,旧Activity会不会走onStop

    不会!

    2.7 介绍Activity的几中启动模式,并简单说说自己的理解或者使用场景

    • standard
      默认模式,可以不用写配置。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。

    • singleTop
      可以有多个实例,但是不允许多个相同Activity叠加。即,如果Activity在栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent方法。

    • singleTask
      只有一个实例。在同一个应用程序中启动他的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent方法。
      如果是在别的应用程序中启动它,则会新建一个task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。

    • singleInstance
      只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。

    2.8 什么是ANR,如何避免他

    image.png

    2.9 Activity的管理机制

    经验总结
    面试官问这个问题,想看看大家对Activity了解是否深入,什么是ActivityRecord,什么是TaskRecord,什么是ActivityManagerService,如果这些大家都能说出来,起码是一个好多年工作经验的老司机了,一般很多对Activity的了解还是停留在界面上

    Activity的管理机制

    简述通过ContentResolver获取ContentProvider内容的基本步骤

    基本步骤:

    得到ContentResolver类对象:ContentResolver cr = getContentResolver()。
    定义要查询的字段String数组。
    使用cr.query();返回一个Cursor对象。
    使用while循环得到Cursor里面的内容。

    Android中如何访问自定义ContentProvider?

    通过ContentProvider的Uri访问开放的数据。

    • 1.ContenResolver对象通过Context提供的方法getContenResolver()来获得。
    • 2.ContenResolver提供了以下方法来操作:insert delete update query这些方法分别会调用ContenProvider中与之对应的方法并得到返回的结果。

    SurfaceView和View的区别是什么?

    SurfaceView中采用了双缓存技术,在单独的线程中更新界面;View在UI线程中更新界面

    你在项目中哪些地方用到了XML?

    XML的主要作用有两个方面:数据交换和信息配置。在做数据交换时,XML将数据用标签组装成起来,然后压缩打包加密后通过网络传送给接收者,接收解密与解压缩后再从XML文件中还原相关信息进行处理,XML曾经是异构系统间交换数据的事实标准,但此项功能几乎已经被JSON(JavaScript Object Notation)取而代之。当然,目前很多软件仍然使用XML来存储配置信息,我们在很多项目中通常也会将作为配置信息的硬代码写在XML文件中,Java的很多框架也是这么做的,而且这些框架都选择了dom4j作为处理XML的工具,因为Sun公司的官方JavaSE实在不怎么好用。Android里的布局文件和配置文件都用的XML。

    Android中定义style和theme的区别

    经验总结:

    一般面试官问这样

    不同点:

    • Theme是应用于Activity或者是整个Application的,作用于单个Activity或者所有Acity,不能作用于某个控件的

    • Style是应用于某个(些)控件,Layout的,作用于控件级别的。

    两者总结一句就是:相对而言Theme是作用于全局的,而Style是作用于局部的。定义方式一样,使用的地方不一样。

    相同点:

    都位于values文件夹下的style.xml中,定义的方法一样,都是控制UI的一堆属性。

    相关文章

      网友评论

          本文标题:Android 面试题之四大组件相关

          本文链接:https://www.haomeiwen.com/subject/ehtbgxtx.html