文章目录
- Android相关
-
- AMS相关
- Activity相关
- Service相关
- Service 如何和 Activity 进行通信?
- BroadcastReciever相关
- ContentProvider相关
- Broadcast的分类?有序,无序?粘性,非粘性?本地广播?
- 自定义View的步骤
- Android中的事件传递机制?
- Handler的原理
- ANR出现的情况有几种? 怎么分析解决ANR问题?
- 内存泄露的场景有哪些?内存泄漏分析工具使用方法?
- 如何避免OOM?
- 如何实现进程保活
- 数据库如何进行升级?SQLite增删改查的基础sql语句?
- Android屏幕适配
- AsyncTask、HandlerThread、IntentService区别和使用
- Bitmap优化
- Android框架相关
- Java相关
- 设计模式相关
- JVM相关
- 高并发相关
- 计算机网络相关
- 算法相关
Android相关
AMS相关
ActivityManagerService是Android中最核心的服务 , 主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块类似。
看源码谈谈AMS启动过程:ActivityManagerService分析——AMS启动流程
Activity相关
SingleTask优化
//如果标签为singleTask的activity在栈顶
onNewIntent()
//如果标签为singleTask的activity不在栈顶
onNewIntent() -> onStart() -> onResume() -> ...
回退栈中的activity不会调用onCreate(),但是这里虽然onNewIntent被调用了,但是Intent中所保存的数据却仍然还是旧数据,因此需要进一步重写。
/***
* 将activity 的创建模式设置为singletask,
* 使用这个方法可以再其他activity想这个activity发送Intent时,这个Intent能够及时更新
*/
@Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
setIntent(intent); //这一句必须的,否则Intent无法获得最新的数据
}
SingleTask优化搭配:
<activity
android:launchMode="singleTask"
android:taskAffinity="com.renly.MainActivity"
android:name="com.renly.MainActivity"
android:screenOrientation="portrait" />
taskAffinity,可以翻译为任务相关性。这个参数标识了一个 Activity 所需要的任务栈的名字,默认情况下,所有 Activity 所需的任务栈的名字为应用的包名,当 Activity 设置了 taskAffinity 属性,那么这个 Activity 在被创建时就会运行在和 taskAffinity 名字相同的任务栈中,如果没有,则新建 taskAffinity 指定的任务栈,并将 Activity 放入该栈中。另外,taskAffinity 属性主要和 singleTask 或者 allowTaskReparenting 属性配对使用,在其他情况下没有意义。
allowTaskReparenting = "true"
在这种情况下,Activity 可以从其启动的任务移动到与其具有关联的任务(如果该任务出现在前台)。
启动模式应用场景
launchMode | 使用场景 |
---|---|
singleTop | 适合启动同类型的 Activity,例如接收通知启动的内容显示页面 |
singleTask | 适合作为程序入口 |
singleInstance | 适合需要与程序分离开的页面,例如闹铃的响铃界面 |
Intent
显式启动:
一般用于启动应用内的Activity
隐式启动:
a.例子:Intent intent = new Intent(String action,Uri uri);
b.一般用于启动应用外的Activity,操作系统会自动把匹配隐式Intent的Acttivity显
示出来供用户选择,匹 配的规则跟Activity声明的 Intent-filter 有关
c.主要组成部分:
(1)action 要执行的操作。也可以通过 setAction() 设置
(2)uri待访问数据的位置。也可以通过 setData() 和 setDataAndType() 设
置。可以是网页的URL,某个文件的,或指向 ContentProvider 的某个内容 URI
(3)操作涉及的的数据类型。setType() 和 setDataAndType()设置。如intent.setType(“text/html”)
(4)可选类别。描述何时,何地或者如何启动某个 Activity。
intent.addCategory(Intent.CATEGORY_LAUNCHER)
Service相关
两种启动方式
1.startService()启动方式:主要用于执行后台计算
2.bindService()启动方式:主要用于和其它组件的交互
说明:这两种状态是可以共存的,即一个Service既可以处于启动状态,也可以同时处于绑定状态。
生命周期
startService() -> onCreate() -> onStartCommand() -> Service运行 -> onDestroy()
bindService() -> onCreate() -> onBind() -> Service运行 -> onUnBind() -> onDestroy()
service 运行于主线程
int onStartCommand(Intent intent, int flags, int startId)会在每次调用startService时回调
FLAG使用START_FLAG_REDELIVERY,意味着当Service因内存不足而被系统kill后,则会重建服务,并通过传递给服务的最后一个 Intent 调用 onStartCommand()
onStartCommand()返回值:
START_STICKY,START_NOT_STICKY,START_REDELIVER_INTENT
Service 如何和 Activity 进行通信?
① 通过绑定服务的方式。在绑定的服务中声明一个Binder类,并创建一个Binder对象,在onBind()函数中返回这个对象,并让Activity实现ServiceConnection接口,在OnServiceConnected方法中获取到Service提供的这个Binder对象,通过这个对象的各种自定义的方法就能完成Service与Activity的通信。
② 通过Intent的方式,在StartService()中需要传入一个Intent对象作为参数,通过这个Intent实例对象进行实现通信。
③ 通过Callback和Handler的方式,在绑定的服务中声明一个Binder类,并创建一个Binder对象,在onBind()函数中返回这个对象,让Activity实现ServiceConnection接口,并且在OnserviceConnected方法中实例化Service中的CallBack接口,并且实现OnDataChange()方法,其中的实质是一段Handler代码,可以在其中完成耗时操作,以这种方式完成通信。
BroadcastReciever相关
写一个类继承BroadcastReceiver重写onReceive方法,注意onReceive是主线程不要做耗时操作否则阻塞10s会ANR,onReceive()中耗时操作不能开线程做,可以使用goAsync()或使用service来做(由于onReceive在结束后会释放资源,依赖线程也很有可能会被释放)
通过LocalBroadcastManager动态注册的Receiver只会在App应用内广播。
两种注册方式
1.静态注册,在注册清单文件进行声明
2.动态注册,在代码中动态进行注册
//静态注册
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="kt.com.MyReceiver"/>
</intent-filter>
</receiver>
//动态注册
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("kt.com.MyReceiver");
registerReceiver(new MyReceiver(),intentFilter);
两种注册方式的区别
1.动态注册的广播是非常驻型广播,此时广播是跟随宿主的生命周期的,宿主不在了广播也就不在了。
2.静态注册的广播是常驻型广播,即应用程序关闭后,依然能够收到广播。