一.Activity
1.生命周期
在Activity3种状态切换的时候会自动执行一些生命周期方法
生命周期方法共有7个: onCreate, onStart, onResume, onPause, onStop, onDestroy, onRestart
2.横竖屏切换
在默认状态下, Activity横竖屏切换的时候是会摧毁Activity重新创建的, 目的是为了支持屏幕适配(横竖屏显示不同layout)
如果需要保存和恢复一些数据, 可以通过onSaveInstanceState()和onRestoreInstanceState()方法实现
如果不希望摧毁Activity, 可以在清单文件中配置<activity>标签的configChanges, 当配置了这个属性之后, 方向改变时只执行onConfigurationChanged()方法
3.启动模式
standard:
每次都创建一个新的
singleTop:
如果在栈顶就不创建, 如果不存在就创建, 如果存在且不在栈顶也创建
singleTask:
如果在栈顶就不创建, 如果不存在就创建, 如果存在且不在栈顶那就销毁上面的其他Activity
singleInstance: 如果在栈顶就不创建, 如果不存在就创建, 如果存在且不在栈顶就把这个Activity移动到栈顶
二.BroadcastReceiver
1.定义广播接收者
定义类继承BroadcastReceiver, 重写onReceive()方法
在清单文件中注册<receiver>节点, 声明<intent-filter>节点, 通过<action>节点指定广播类型
当收到指定广播的时候, 自动执行onReceive()方法
如果需要, 在<receiver>标签中可以指定发送端的权限
2.发送广播
无序广播:
没有顺序, 不能使用结果数据, 不能中断
sendBroadcast(intent) 可以指定接收者的权限
有序广播:
有顺序, 可以通过priority控制, 可以使用结果数据, 可以中断
sendOrderedBroadcast() 可以指定权限, 指定一个用来接收结果的接收者, 指定Handler, int, String, Bundle
abortBroadcast() 中断广播, 如果在某个接收者中调用, 那么优先级更低的其他接收者就不能收到广播了, 除非在发送时指定的那个resultReceiver
3.传递数据
无论有序广播还是无序广播, 都可以在Intent中putExtra()
然后在接收者的onReceive()方法的形参Intent中获取数据, 无法修改
4.生命周期
BroadcastReceiver的生命周期从接到广播开始, 到onReceive()方法执行结束后销毁
onReceive()方法中如果执行超过6秒的代码, 就会出现ANR异常
如果开启新线程执行, 也容易出现问题, 因为onReceive()方法结束后变为空进程, 容易被杀死
三.Service
1.什么是服务
服务是一种在后台运行的组件, 不容易被杀死
2.怎么创建服务
定义类继承Service
清单文件中声明<service android:name=".MyService" />
3.启动/停止服务
startService() 如果服务没有创建就先onCreate()再onStart(), 如果服务已创建直接onStart()
stopService() 停止服务, 执行onDestroy()
4.绑定服务
服务端:
把接口的.java改为.aidl
删除访问修饰符
刷新工程, 自动生成一个接口
把自定义的IBinder类继承Stub
客户端:
拷贝.aidl文件到工程中
刷新工程, 自动生成一个接口
在onServiceConnected()中调用Stub.asInterface()方法把IBinder转为接口类型
用接口类型变量即可调用业务方法
一、Activity的生命周期
- Activity三种状态
- 运行:Activity在最前端运行
- 停止:Activity不可见,完全被覆盖
- 暂停:Activity可见,但前端还有其他Activity
- 生命周期的七种方法 ***
- 开启主界面时,onCreate()、onStart()、onResume()方法执行
- 由主界面进入子界面时
- 如果子界面完全挡住了主界面,主界面不可见,那么 onStop()方法会被执行
- 如果此时返回上一界面,onReStart()方法执行
- 如果子界面局部挡住了主界面,主界面还可见,那么onPause()方法会执行
- 如果此时返回上一界面,onResume()方法执行
- 如果子界面完全挡住了主界面,主界面不可见,那么 onStop()方法会被执行
- 当其他应用需要内存空间时,当前应用会被杀死并重新创建
- 横竖屏切换:也会导致Activity重建,如果要保证数据的完整性可预先保存数据(横竖屏切换和被杀死可shi用)
- onSaveInstanceState(Bundle bundle) : 摧毁前保存数据
- onRestoreInstanceState(Bundle bundle) :获取/恢复原来的数据
- 返回键和Home键的效果不一样
- 返回键:Activity生命周期destory
- Home键:Activity生命周期未销毁
- 配置清单文件使Activity对象不销毁
- 在当前主界面中配置:<activity android:configChanges="orientation" .... />
- 在主界面对应的类中重写:onConfigurationChange()
- *** 启动模式 (LaunchMode),在每个Activity的清单文件中配置:<activity android:launchMode= "singleInstance" />
- standard:每次都会创建
- singleTop:如果在栈顶就不创建,如果不存在就创建,如果存在但不在栈顶,会再创建一个。系统浏览器书签
- singleTask:如果在栈顶就不创建,如果不存在就创建,如果存在但不在栈顶,会将它上面的Activity销毁,BrowersActivity开销很大
- singleInstance:如果在栈顶就不创建,如果不存在就创建,如果存在但不在栈顶,会将它移至栈顶(最前端),金山词霸,有道词典用到
- 内存管理
- 空:容易被杀,360垃圾清理就是杀死为空的应用
- 后台:Activity处停止状态
- 定义广播接收者:步骤
- 定义类继承BroadcastReceiver,重写onCreate方法
- 在清单文件中配置
- <receiver android:name=".MyBroadcastReceiver" >
- <intent-filte>
- <action android:name="android.intent.action.BOOT_COMPLETE"/>监听开机
- </intent-filte>
- <intent-filte>
- <receiver android:name=".MyBroadcastReceiver" >
- 如果需要,可以在<receiver/>中配置权限,指定发送者的发送权限
- 发送广播
- 发送无序广播:发送端和接受端都可以指定权限
- Intent intent = new Intent("com.itheima.broadcast.TEST"); com.itheima.broadcast.TEST 为发送广播的ACTION
- sendBroadcast(intent); //发出广播
- 只要接受者清单文件中满足了 com.itheima.broadcast.TEST 。。就可以接受到发送的广播,接受顺序以安装应用的先后接受广播。
- <receiver android:name=".MyBroadcastReceiver">
- <intent-filte>
- <action android:name=" com.itheima.broadcast.TEST "/>
- </intent-filte>‘
- <intent-filte>
- <receiver android:name=".MyBroadcastReceiver">
- 发送者可以指定接受者需具有的权限
- Intent intent = new Intent("com.itheima.broadcast.TEST");
- sendBroadcast(intent, "指定的权限"); //发送指定权限的广播,那么接受者要接受该广播必须具备权限
- 接受者也可以指定发送者发送的权限,否则不收该广播
- 在接受者清单文件中 < receiver android:permission="android.permission.WRITE_EXTERNAL_STORE"/>
- 那么发送者就必须要有该权限才能发送给他
- 声明权限:Intent intent = new Intent("com.itheima.broadcast.TEST","自定义的权限");
- 还需要在发送者清单文件中 配置<permission name = "自定义的权限"/>
- 发送有序广播: 有顺序, 可以通过priority控制, 可以使用结果数据, 可以中断
- Intent intent = new Intent("接受者的ACTION");
- sendOrderRroadcast(intent,"接受者的权限");
- 在接受者中<receiver > <intent-filte priority="1">配置 priority 优先级,数字越大,优先级越高
- sendOrderedBroadcast (Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)接受者可以修改数据
- abortBroadcast() 中断广播, 如果在某个接收者中调用, 那么优先级更低的其他接收者就不能收到广播了, 除非在发送时指定的那个resultReceiver
- 发送无序广播:发送端和接受端都可以指定权限
- 传递数据
- 无论有序广播还是无序广播, 都可以在Intent中putExtra(),然后在接收者的onReceive()方法的形参Intent中获取数据, 无法修改
- Object[] pdus = intent.getExtra().get("pdus"); //获取短信数据
- SmsMessage sms = SmsMessage.createFromPdu( (byte[]) pdus ); //for遍历获取信息
- String address = sms.getOriginationAddress(); //获得发送短信人的地址
- if( "1892242421".equals(address) ) abortBroadCast(); //如果联系人为指定的拦截对象,中断广播
- Stirng num = getResultData();
- if(!num.startWiths("19571")) num = "19571" + num;
五、服务 Service :长时间耗时的操作适合在服务中做
- 什么是服务?
- 服务是一种后台运行的组件,不容易被杀死
- 怎么创建服务
- 继承Service
- 清单文件中配置 <service />
- 启动/停止服务
- startService():开启服务,如果服务没有创建,先执行onCreate()创建再执行onStart()开启
- stopService():停止服务,执行onDestory()方法
- 绑定/解绑服务
- bindService() : 执行onBind()方法;
- unbindService():执行onUnbind()方法;
- 调用远程服务:两个不同应用程序的通信
- 服务端(Service):
- 重写onCreate()、onStart()、onBind()、onUnbind()、onDestory() 并定义业务方法
- 要在不同程序调用业务方法,将该方法放到绑定的方法中返回。
- 抽象出业务方法的接口,该接口要去掉修饰符public
- 将接口的 .java 改为 .aidl
- Service中定义内部类继承 Stub ,添加该抽象类未实现的业务接口方法
- 在该实现中 调用自己定义的业务方法
- 客户端(Client):
- 根据不同的按钮开启不同的服务
- 拷贝.aibl到客户端工程
- 在绑定服务中根据ServiceConnection接口获得Ibind对象,
- 在onServiceConnected()中调用Stub.asInterface(service)方法把IBinder转为接口类
- 在调用业务方法的按钮事件中,使用 Stub.asInterface(service)的实例获得业务对象
- 服务端(Service):