Android面试相关(二)安卓篇-四大组件

他山之石可以攻玉:
https://blog.csdn.net/luyuqin0115/article/details/79815560 转载于 luyuqin0115
https://blog.csdn.net/yuzhiqiang_1993/article/details/72675497 转载于 喻志强
注:本文借鉴了上述两个blog中部分内容,作者若感到有侵犯版权的话,请及时与我联系,我会尽快修改,谢谢。

四大组件

Activity

Activity是安卓四大组件之一,应该是我们用的最多的一个组件了。它主要负责的是提供界面用于和用户交互,使用户可以在界面上进行点击、滑动等操作。可以理解为MVC中的V(View)。
基本上面试都会问到以下几个问题:

1.Activity的生命周期
 onCreate()    //onCreate是Activity被创建的时候调用,是生命周期的第一个方法,我们新建的Activity几乎都会重写这个方法,在这里我们可以做一些初始化操作等,如加载布局文件。
 onStart() //表明Activity正在启动,此时处于用户可见状态,但是并不能与用户交互
 onResume() //表明Activity已经处于前台状态,可以与用户交互了。此时Activity就处于Running状态了
 ----------------------------------------------以上 为 Activity 启动过程------------------------------------------------------------------------------
 onPause() //表明Activity处于paused状态,此时Activity无法与用户交互
 onStop() //一般在onPause()后执行,此时Activity处于不可见状态
 ----------------------------------------------以上 为退出但不销毁Activity时执行的过程,如点击HOME键-------------------------------
 onRestart() //表明Activity重新启动,从不可见变为可见状态
 ----------------------------------------------以上 为重新回到Activity时执行的方法-------------------------------------------------------------
 onDsetory() //表明Activity正在被销毁,是整个生命周期方法中的最后一个方法,在该方法中我们可以做一些资源回收的工作。
 ----------------------------------------------以上 为销毁Activity时执行的方法-------------------------------------------------------------------

上述操作为正常时候的生命周期,如果系统内存不足时导致要对Activity进行强行回收,此时生命周期就不会正常执行了。
我们可以使用onSaveInstanceState这个方法进行一些数据保存的工作,然后在onCreate或onRestoreInstanceState方法中恢复数据。

2.Activity的启动模式(待完善)

1.standard
默认的启动模式,每次启动Activity的时候都会创建一个新的实例。不会复用Activity,对内存消耗较大。

2.singleTop
栈顶复用模式,如果要创建的Activity已经在栈顶的话,那么不会重新创建,直接复用,否则,仍然会重新创建。
适合接受通知启动的内容页面,例如:某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。

3.singletask
栈内复用模式,如果要创建的Activity在栈内已经存在的话,不会重新创建,直接复用栈内存在的Activity,且会调用onNewIntent()方法,并且将该Activity以上的所有的Activity销毁。
适合做程序的入口点,例如浏览器的主界面,不管从多少个应用启动浏览器,只会启动主界面一次,其余的情况都走onNewIntent,并且会清空主界面上面的其他页面

4.singleInstance
单一实例,独享一个任务栈,整个手机操作系统里面只有一个实例存在。用的较少。
适合需要与程序分离的页面
例如:闹铃提醒,将闹铃提醒与闹铃设置分离

3.Android中的进程优先级

前台>可见>服务>后台>空

前台:包含正在处于和用户交互的Activity或者是前台Activity绑定了service
可见:activity处于可见状态但不可与用户进行交互
服务:包含一个service服务的进程
后台:处于不可见的状态下(比如按了home键)
空:没有活跃的组件 只是为了缓存的目的存在的,随时都可能被系统杀掉

4.Android应用中的每个Activity都应该在AndroidManifest.xml配件文件中注册,否则系统将不识别也不执行该Activity
5.活动被回收,Activity状态保存于恢复

Activity提供了onSaveInstanceState()回调方法,这个方法可以保证在活动回收之前被调用,
onSaveInstanceState()方法会携带一个Bundle类型的参数,Bundle提供了一些方法用于保存数据

 @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("data", "保存数据");
    }

保存的数据在onCreate()方法中可获取

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(savedInstanceState!=null){
        String data = savedInstanceState.getString("data");
        }
 }
6.(想到了再写)

Service

1.Service基础知识

Service是一种能在后台执行耗时任务的没有界面显示的组件。需要注意的是Service和BroadCastReceiver都是运行在主线程的,所以,Service本身不能做耗时操作,而是通过子线程去完成!

2.Service和Thread的区别

详细可以看这篇博客service和thread的区别
讲的非常仔细。

在这里做个总结:
Thread和Service实际上是没有任何关系,只不过因为字面上的意思,我们可能会误解为Service可以执行耗时任务的,实际上Service是运行在主线程上的,也就是说,Service本身并不能做耗时操作,一般都是在Service中启线程去执行耗时任务。

Thread是程序执行的最小单元,是独立与Activity运行的,也就是说,如果我们在Activity中启线程去执行任务,即使这个activity被销毁了,该任务也会继续执行。
而Service是Android中一种机制,在一些运行在后台的不需要界面的地方可以使用Service。

3.Service的生命周期

onbind/onCreate/onStartCommand/ondestory

onBind(): 该方法返回的是一个IBinder接口,当我们使用bindService的时候才会被调用
onCreate(): 服务首次创建时调用,注意,只有service第一个被创建时才会调用
onStartCommand(): 每次调用startService的时候都会执行该方法,该方法有一个int类型的返回值

分别是:START_STICKY、START_NOT_STICKY、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY。
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后一定能重启。

onDestory(): 服务销毁时调用,在这里可以做一些资源回收操作。

4.Service的两种启动方式

startService 和 bindService

startService
1.定义一个类继承自Service
2.在清单配置文件中声明
3.使用Context.startService(Intent)启动Service
4.调用Context.stopService(Intent)停止Service

 Intent intent = new Intent();
 intent.setClass(activity, UpdateApkService.class);
 activity.startService(intent);//开启服务
 activity.stopService(intent);//停止服务

执行startService时,Service会经历onCreate->onStartCommand。当执行stopService时,直接调用onDestroy方法。调用者如果没有stopService,那么即使Activity被销毁了,Service也会继续执行,下次调用者再起来仍然可以stopService。

bindService
1.创建一个类继承自Service,并在类中创建一个实现IBinder接口的实例对象并提供公共方法。

    /*这里定义一个类  用于返回Service*/
    public class MyBinder extends Binder {
        public MyService getService() {
            return MyService.this;
        }

    }
    /*提供一个公共方法*/
    public Date getTime(){
        return new Date();
    }

2.在onBind()中返回自定义的IBinder实例

  private MyBinder myBinder=new MyBinder();


    @Override
    public IBinder onBind(Intent intent) {
        return myBinder;
    }

3.在需要调用的地方,从onServiceConnected中获取IBinder实例并调用公共方法

  sc = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.i("aaa","onServiceConnected");
                MyService.MyBinder myBinder = (MyService.MyBinder) service;
                Date date = ((MyService.MyBinder) service).getService().getTime();
                Log.i("aaa",date.toString());
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };

        Intent intent = new Intent(this, MyService.class);
        bindService(intent, sc, BIND_AUTO_CREATE);

执行bindService时,Service会经历onCreate->onBind。这个时候调用者和Service绑定在一起。调用者调用unbindService方法或者调用者Context不存在了(如Activity被finish了),Service就会调用onUnbind->onDestroy。这里所谓的绑定在一起就是说两者共存亡了。

5.Service的生命周期与启动方法由什么区别?

startService():开启Service,调用者退出后Service仍然存在。
bindService():开启Service,调用者退出后Service也随即退出。

BroadcastReceiver

四大组件之一,在Android中,Broadcast是一种广泛运用在应用程序之间传输信息的机制,Android中我们要发送的是一个intent,intent可易携带我们需要传输的数据。

广播的使用场景
1.同一app中不同组件之间的数据传递
2.不同app之间组件的数据传递

广播的种类

1.普通广播 Context.sendBroadcast

是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎同时都会在同一时刻受到这条广播消息,这种广播的效率比较高,但同时也意味着它是无法被截断的
2.有序广播 Context.sendOrderedBroadcast 根据优先级传播,优先级高的接收器可以阻止继续传播或修改数据
是一个同步执行的广播,广播发出后,同一时刻只有一个广播接收器能够受到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。所有此时的广播接收器是有先后顺序的,优先级高的先受到广播,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器就无法接收到广播消息了

3.本地广播
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
lbm.sendBroadcast(new Intent(LOCAL_ACTION));
只会在应用内部传播,相对来说数据安全。

广播的注册方式

1.静态注册 在清单配置文件中声明,即使进程被杀死,该广播仍然运行

<receiver android:name=".MyReceiver">  
            <intent-filter>  
                <action android:name="android.intent.action.MY_BROADCAST"/>  
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>  
        </receiver>  

2.动态注册 在代码中注册,受activity生命周期的影响。

MyReceiver receiver = new MyReceiver();  
          
IntentFilter filter = new IntentFilter();  
filter.addAction("android.intent.action.MY_BROADCAST");  
          
registerReceiver(receiver, filter);  

内部实现机制
1.自定义BroadcastReceiver,重写onReceive()方法
2.通过Binder机制向AMS(Activity Manager Service)进行注册
3.广播发送者通过Binder机制向AMS发送广播
4.AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadCastReceiver相应的消息循环队列中
5.消息循环执行拿到广播,回调BroadCastReceiver中的onReceive()方法。

LocalBroadcastManager
1.使用LocalBroadcastManager发送的广播只能在app内部传播,因此数据传输很安全。
2.比系统广播更加高效,底层是通过Handler发送message实现的。

1.广播使用的方式和场景

创建一个广播接收器,新建一个类让它继承BroadCast,并重写onReceive()方法就行
使用场景:
1.App全局监听,这种主要用于在AndroidManifest中静态注册的广播接收器,一般我们在收到该消息后,需要做一些相应的动作,而这些动作与当前App的组件,比如Activity或者Service的是否运行无关,比如我们在集成第三方Push SDK时,一般都会添加一个静态注册的BroadcastReceiver来监听Push消息,当有Push消息过来时,会在后台做一些网络请求或者发送通知等等。
2.组件局部监听,这种主要是在Activity或者Service中使用registerReceiver()动态注册的广播接收器,因为当我们收到一些特定的消息,比如网络连接发生变化时,我们可能需要在当前Activity页面给用户一些UI上的提示,或者将Service中的网络请求任务暂停。所以这种动态注册的广播接收器适合特定组件的特定消息处理

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

动态注册:在代码中注册,动态广播最好在Activity 的 onResume()注册、onPause()注销,在onResume()注册、onPause()注销是因为onPause()在App死亡前一定会被执行,从而保证广播在App死亡前一定会被注销,从而防止内存泄露
非 常驻系统,跟随组件的生命周期变化而变化,组件结束,广播结束。

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.ACTION_SHUTDOWN");
registerReceiver(new CommonBroadcastReceiver(),intentFilter);

静态注册:在AndroidManifest.xml中注册
常驻系统,不受组件的生命周期影响,即便应用退出,广播还是可以被接受,耗电,占用内存

<receiver android:name=".broadcast.CommonBroadcastReceiver">
            <intent-filter>
                <!-- 关机广播 -->
                <action android:name="android.intent.action.ACTION_SHUTDOWN" />
            </intent-filter>
</receiver>
3.广播发送和接收的原理

继承BroadcastReceiver,重写onReceive()方法。
通过Binder机制向ActivityManagerService注册广播。
通过Binder机制向ActivityMangerService发送广播。
public abstract void sendBroadcast(Intent intent);
1
ActivityManagerService查找符合相应条件的广播(IntentFilter/Permission)的
BroadcastReceiver,将广播发送到BroadcastReceiver所在的消息队列中。
BroadcastReceiver所在消息队列拿到此广播后,回调它的onReceive()方法。

4.Binder机制

Android Binder是用来做进程通信的,Android的各个应用以及系统服务都运行在独立的进程中,它们的通信都依赖于Binder。

5.Android里的Intent传递的数据有大小限制吗,如何解决?

Intent传递数据大小的限制大概在1M左右,超过这个限制就会静默崩溃。处理方式如下:

进程内:EventBus,文件缓存、磁盘缓存。
进程间:通过ContentProvider进行款进程数据共享和传递。

ContentProvider

1.谈谈你对ContentProvider的理解

ContentProvider管理android以结构化方式存放的数据。他以相对安全的方式封装数据并且提供简易的处理机制。Content provider提供不同进程间数据交互的标准化接口。保证被访问数据的安全性。内容提供器可以选择只对哪一部分数据进行共享,从而保证我们程序中的隐私数据不会有泄漏的风险。

2.说说ContentProvider、ContentResolver、ContentObserver 之间的关系

ContentResolver中提供了一系列的方法用于对数据进行CRUD,内容URI给内容提供器ContentProvider中的数据建立了唯一标识符,ContentObserver监听Uri数据的变化

①ContentProvider:管理数据,提供数据的增删改查操作,数据源可以是数据库、文件、XML
网络等。ContentProvider为这些数据提供了统一的接口,可以用来做进程间数据共享
②ContentResolver:ContentResolver可以不同的URI操作不同的ContentProvider中的数据库,外部进程可以通过ContentResolver 与ContentProvider进行交互
③ContentObserver :观察ContentProvider中的数据变化,并将变化通知给外界。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值