第七天
来源:互联网 发布:万网域名登录网址 编辑:程序博客网 时间:2024/04/30 08:52
1、Service特点
[1] Service在Android中是一种长生命周期的组件,它不实现任何额用户界面,是一个没有界面的Acrivity
[2] Service长期在后台运行,执行不关乎界面的一些操作,例如:网易新闻服务每隔一分钟去服务器查看是否有最新的新闻
[3] Service和Thread有点相似,但是使用Thread不安全,不严谨
[4] Service和其他组件一样,都是运行在主线程中,因此不能用它来做耗时的操作,如果想要做耗时的操作,那么要在服务的内部创建子线程
2、什么时候使用Service,什么时候使用Thread呢?
[1] 如果在整个过程中这个线程都无需和用户进行交互,那么选择Service
[2] 如果线程在执行的过程中需要和用户进行交互,那么选择Thread
3、android中的进程
[1] 进程优先级由低到高
Foreground process 前台进程 优先级最高 相当于Activity执行了onResume()方法 用户正在交互
Visible process 可视进程 用户可见但是无法操纵 相当于Activity执行了onPause()方法
Service process 服务进程 通过startService()开启了一个服务
Background process 后台进程 相当于Activity执行了onStop()方法 界面不可见 但是Activity并没有被销毁
Empty process 空进程 不会维持任何组件的运行
4、Start方式开启服务(StartService)
[1] 创建一个类继承Service重写其生命周期方法onCreate()、onStartCommand()、onStop()、onDestroy()方法
[2] 特点:
[1] 第一次点击开启服务会执行onCreate()和onStartCommand()
[2] 第二次点击开启服务只会执行onStartCommand()
[3] 服务一旦开启,就会在后台长期运行,只能通过用户手动停止才可以
5、Service 和 Thread之间的关系
[1] Thread只能在开启其的Activity中进行操作,一旦这个脱离这个Activity就无法获取这个线程的引用,而任何一个Activity都可以绑定同一个Service,如果在Service开启子线程,那么就可以获取线程的数据,所以Service并不是线程
[2] Service如果不在清单文件中指定android:process=".remote"那么是一个local Service那么就和Activity在同一个进程中,如果指定了这个选项,那么就在不同的进程中运行
6、电话监听器案例
[1] 创建一个类继承Service
[2] 重写onCreate()和onDestroy()方法
public class PhoneListenerService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
//[1] 拿到TelephonyManager的实例
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
//[2]
telephonyManager.listen(new MyPhonyListener(),PhoneStateListener.LISTEN_CALL_STATE);
}
private class MyPhonyListener extends PhoneStateListener{
MediaRecorder recorder;
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state){
case TelephonyManager.CALL_STATE_IDLE : //当电话空闲的时候
if(recorder != null){
recorder.stop();
recorder.reset();
recorder.release();
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK : //当电话接听的时候
Log.d("offhook","开始录音");
recorder.start();
break;
case TelephonyManager.CALL_STATE_RINGING: //当电话响铃的时候
//[1] 获取录音记录
recorder = new MediaRecorder();
//[2] 设置录音来源
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//[3] 设置录音格式
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
//[4] 设置了录音编码
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//[5] 设置录音输出目录
recorder.setOutputFile(Environment.getExternalStorageDirectory().getPath()+"/audio.mp4");
try {
recorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
public void onDestroy(){
}
}
[3] 创建一个类继承Broadcast
[4] 重写onReceive()方法
[5] 在onReceive()里面开启Service
public class ServiceStartReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent(context, PhoneListenerService.class);
context.startService(intent1);
}
}
7、通过bindService调用
[1] 创建一个类继承Service
public class BindService extends Service
[2] 重写onCreate()、onBind()两个方法
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
[3] 在ctivity中使用bindService()绑定服务
myServiceConnection = new MyServiceConnection();
bindService(intent,myServiceConnection,BIND_AUTO_CREATE);
private class MyServiceConnection implements ServiceConnection{
//当连接成功的时候调用
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.d("bindService","绑定服务");
}
//当服务解绑的时候调用
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d("unbindService","解绑服务");
}
}
[4] 使用unbindService解绑
unbindService(myServiceConnection);
[5] 使用bindService的特点
[1] 第一次创建的时候调用onCreate()和onBind()方法
[2] 当onBind方法返回null的时候onServiceConnected()方法不执行
[3] 服务不可多次绑定
[4] 不求同时生,但求同时死,指的是绑定者(Activity)和被绑定者(Service)之间的关系
[5] 通过bind绑定的服务无法在设置页面找到相当于隐形的服务
8、如何在Activity里面调用Service里面的方法
[1] 创建服务
[3] 将这个类的对象返回
public IBinder onBind(Intent intent) {
return new MyBinder();
}
private void method(){
Toast.makeText(getApplicationContext(),"调用了",Toast.LENGTH_SHORT).show();
}
- [2] 写一个内部类继承Binder方法,然后在这个类里面调用Binder的方法
public class MyBinder extends Binder{
public void callMethod(){
method();
}
}
[4] 在Activity里面获取对象,然后调用
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(this,TestService.class);
bindService(intent,new MyConn(),BIND_AUTO_CREATE); //初始化绑定,走onBinder
}
public void click(View view){
service.callMethod(); //调用Binder里面的方法
}
private class MyConn implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
service = (TestService.MyBinder) iBinder; //获取Binder对象
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
}
9、在接口中调用服务方法
[1] 接口的好处:接口可以暴露出程序员想要向用户暴露的方法。用户只需要实现需要实现的方法
[2] 实现步骤
[1] 定义一个接口
public interface IService {
public void callMethod();
}
[2] 实现这个接口,重写需要未实现方法
private class MyBinder extends Binder implements IService{
public void callMethod(){
method();
}
}
[3] 获取在这个实例,通过多态的方式实现
service = (IService) iBinder;
10、需求:即想让服务长期运行,又想调用服务里面的方法
步骤
[1] 开启服务startService
[2] 绑定服务 获取服务方法bindService
[3] 解绑服务 unbindService
[4] 停止服务 stopService
11、aidl
本地服务:运行在自己应用中的服务
远程服务:运行在其他应用中的服务
实现进程间通信 IPC
aidl:android interface definition language 接口描述语言。
用途:专门用来解决进程间通信。
总结:使用aidl的步骤
[1] 把IService.java文件变成一个aidl文件
[2] aidl语言不认识public
[3] 自动生成一个Iservice.java文件 ,系统自动生成一个stub类
[4] 我们自己定义的中间人直接继承Stub类
[5] 保证2应用的aidl文件是同一个 保证aidl文件所在的报名相同
[6] 获取中间人对象的方法不一样了 Stub.asInterface()拿到中间人对象
Android Studio配置aidl文件的方法
[1] 在Server端直接新建aidl文件
[2] 将创建出来的文件所在的包名复制出来Copy Reference,将完整包名复制出来,在client端创建包
[3] 然后build就可以了
0 0
- 第七天
- 第七天
- 第七天
- 第七天
- 第七天
- 第七天
- 第七天
- 第七天
- 第七天
- 第七天
- 第七天
- 第七天
- 第七天
- php七天入门教程第七天
- 世界杯第七天
- 项目组长第七天
- IBM实习第七天
- 第七天 目标
- windows查看端口占用情况
- spark-2.0.2变动
- spring 注解详解
- BZOJ3144: [Hnoi2013]切糕
- 机器人入门困惑之资料总结
- 第七天
- 第八天
- aotulayout适配可能会遇到的问题
- 学习python的第三十二天-列表,元组,字典
- H-Find them, Catch them POJ 1703
- 第九天
- 计算机专业导论简易思维导图
- 第十天
- 强大的数据库ORM框架-GreenDao增删改查篇