android 沉淀 - 四大组件

2019-06-01  本文已影响0人  前行的乌龟

Activity

大家最熟悉的吧,但是熟悉并不代表了解一切,但往往越是被熟知的越是被问及的越深,面试时看=有的面试官可以喜欢在这里难住面试者的

1. 生命周期

以下的操作会触发 Activity 的生命周期函数:

2. 启动模式

启动模式这个一定会问,但是必会的

除了 standard 之外其他3个模式,复用所在 Activity 时都会触发 onNewIntent 方法,这个方法接受一个 intent 参数,可以拿到用户传递过来的数据

调用顺序如下:

3. 数据保存与恢复

2 个方法:

调用时机 : 注意是 Activity 容易被销毁的时候调用, 是容易被销毁, 但是也可能没有销毁就调用了

onSaveInstanceState 方法总是在 onStop 之前调用,但是不去确定是在 onPause 之前或之后调用。另外 onSaveInstanceState 保存的数据有有效期和 app 进程相同,app 进程要是被销毁了那么保存的数据也就没了

4. 系统 kill 时的生命周期

非常郁闷的是当系统因为内存不足要回收 Activity 占用的资源时,有时 Activity 在 onPause() 之后就会被销毁,onStop(),onDestory() 根本不会执行,所以很多时候我们要在 onResume()注册监听,onPause() 注销监听也是没办法的事,尤其是对于广播接收器来说,这可能造成内存泄露问题


Service

Service 既服务,被认为是没有 UI 的 Activity,非常相似

Service 的特点(可能被问及的点):

2种 Service 启动方式分别对应的生命周期:


如何保证Service不被杀死:

更多更详细请看:


广播

1. 静态注册参数
<receiver 
    android:enabled=["true" | "false"]
//此broadcastReceiver能否接收其他App的发出的广播
//默认值是由receiver中有无intent-filter决定的:如果有intent-filter,默认值为true,否则为false
    android:exported=["true" | "false"]
    android:icon="drawable resource"
    android:label="string resource"
//继承BroadcastReceiver子类的类名
    android:name=".mBroadcastReceiver"
//具有相应权限的广播发送者发送的广播才能被此BroadcastReceiver所接收;
    android:permission="string"
//BroadcastReceiver运行所处的进程
//默认为app的进程,可以指定独立的进程
//注:Android四大基本组件都可以通过此属性指定自己的独立进程
    android:process="string" >

//用于指定此广播接收器将接收的广播类型
//本示例中给出的是用于接收网络状态改变时发出的广播
 <intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>
2. 继承 BroadcastReceiver

BroadcastReceiver 是官方组件,自然是要像 Activity 一样去继承的

public class SdCardBroadcastReceiver extends BroadcastReceiver {
    
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction ();
        if ("android.intent.action.MEDIA_MOUNTED".equals(action)) {
            System.out.println("sd卡已挂载");
        } else if ("android.intent.action.MEDIA_UNMOUNTED".equals(action)) {
            System.out.println("sd卡已卸载");
        }

       String data = intent.getStringExtra("key");
    }
}

从 intent 中可以拿到 action 和 bundle 传递的数据

3. 广播的类型

3.1 发送无序广播

public void startBroadcast(View view){
        //开启广播
        //创建一个意图对象
        Intent intent = new Intent();
        //指定发送广播的频道
        intent.setAction("com.example.BROADCAST");
        //发送广播的数据
        intent.putExtra("key", "发送无序广播,顺便传递的数据");
        //发送
        sendBroadcast(intent);
    }

3.2 发送有序广播

    public void sendOrderedBroad(View view) {
        Intent intent = new Intent();
        intent.setAction("com.example.ORDERED");
        // 发送无序广播
        sendOrderedBroadcast(intent,//意图动作,指定action动作
                null, //receiverPermission,接收这条广播具备什么权限
                new FinalReceiver(),//resultReceiver,最终的广播接受者,广播一定会传给他
                null, //scheduler,handler对象处理广播的分发
                0,//initialCode,初始代码
                "每人发10斤大米,不得有误!", //initialData,初始数据
                null//initialExtras,额外的数据,如果觉得初始数据不够,可以通过bundle来指定其他数据
                );
    }

有序广播的特点是按照 xml 中的优先级从高到底开始接受,先接受的 recriver 可以把数据处理之后再交给下一级或者不在传递,很想网络里的拦截器

priority 越大优先级越高


public class ShengReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent)        

        // 获取广播的数据
        String data = getResultData();       
 
        // 修改之后再给下一级
        setResultData("中央下达福利,每人5斤大米");

        // 终止广播,权限小的接收者就接收不到广播了
        abortBroadcast();
    }
}
4. 动态注册方法

注意广播注册注销的最佳时机在 onResume、onPause,因为系统回收 Activity 时后面的生命周期可能就不会走了

上面在 AndroidManifest 中声明的都叫做静态广播,动态注册的广播就是不在AndroidManifest 中声明,用代码启动,解绑,但是要注意自 8.0 开始,不在允许静态注册的广播,必须手动代码注册

// 选择在Activity生命周期方法中的onResume()中注册
@Override
  protected void onResume(){
      super.onResume();

        // 手动注册广播
        var intentFilter = IntentFilter()
        intentFilter.addAction("AAA")
        registerReceiver(receiver, intentFilter)

        // 发送给广播
        var intent = Intent("AAA")
        sendBroadcast(intent)
 }

 @Override
 protected void onPause() {
     super.onPause();
      // 解绑广播
     unregisterReceiver(mBroadcastReceiver);
     }
}

重复注册、重复注销也不允许,不注销会有内存泄露问题的

5. 不同注册方式的广播回调 OnReceive

对于不同注册方式的广播接收器回调 OnReceive(Context context,Intent intent)中的 context 返回值是不一样的:


进程

android 的进程主要了解有优先级,用来配合 Service 保活策略

android 进程优先级5个档:

怎么理解呢,简单来说:

上面是简单理解,详细请看:

但是和理论不同的是,Service 优先级首先参考的不是自己的优先级,而是首先参考所在 app 进程的页面活动

具体可以参考:


上一篇下一篇

猜你喜欢

热点阅读