day08 服务

pasting
1    进程的概念
    [1]Android下四大组件都运行在主线程下
    [2]服务是在后台下运行    没有界面的 activity    
              service 是 activity的大爷
进程的优先级
    [1]Foreground process    前台进程    优先级最高    相当于activity执行了onResume方法    用户正在交互
    [2]Visible    process    可视进程    一直影响用户看得见相当于activity执行了onPause方法
    [3]service    process    服务进程    通过startService方法开启一个服务
    [4]Background    process        后台进程    相当于activity执行了onStop方法    界面不可见    但是activity并没有销毁
    [5]Empty    process    空进程    不会维持任何组件运行
2    start方式开启服务的特点
    [1]定义四大组件的方式是一样的
    [2]定义一个类继承Service
    [3]第一次点击按钮开启服务    服务执行onCreate方法和onStartCommand方法
    [4]第二次点击按钮    再次开启服务    服务执行 onStartCommand方法
    [5] 服务一旦被开启    服务就会后台长期运行    直到用户手工停止

补充:股票应用

3    电话qie听器案例
    TelephoneManager
实现步骤
    [1]定义一个服务    开启服务    记得在清单文件配置服务
 
    [2]在服务的onCreate方法里面    获取TelephoneManager
 
   
  1. // [1]获取teltphonemanager的实例
  2. TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    [3]注册电话的监听
 
   
  1. / [2]注册电话的监听
  2. tm.listen(new MyPhoneStateListener(),
  3. PhoneStateListener.LISTEN_CALL_STATE);
    [4]定义一个类用来监听电话的状态
 
   
  1. // 定义一个类用来监听电话的状态
  2. private class MyPhoneStateListener extends PhoneStateListener {

  3. // 当电话设置状态发生改变的时候调用
  4. @Override
  5. public void onCallStateChanged(int state, String incomingNumber) {

  6. // [3]具体判断一下电话的状态
  7. switch (state) {
  8. case TelephonyManager.CALL_STATE_IDLE:// 空闲状态
  9. if(recorder!=null){
  10. recorder.stop();
  11. recorder.reset(); // You can reuse the object by going back to
  12. // setAudioSource() step
  13. recorder.release(); // Now the object cannot be reused
  14. }

  15. break;
  16. case TelephonyManager.CALL_STATE_OFFHOOK:// 接听状态

  17. System.out.println("开始录音");
  18. recorder.start(); // Recording is now started
  19. break;
  20. case TelephonyManager.CALL_STATE_RINGING:// 响铃状态

  21. System.out.println("准备录音机");
  22. try {
  23. //[1]创建MediaRecorder实例
  24. recorder = new MediaRecorder();
  25. //[2]设置音频的来源
  26. recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  27. //[3]设置输出的格式
  28. recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
  29. //[4]设置音频的编码方式
  30. recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  31. //[5]设置存放的路径
  32. recorder.setOutputFile("/mnt/sdcard/luyin.3gp");
  33. //[6]准备录
  34. recorder.prepare();
  35. } catch (IllegalStateException e) {
  36. // TODO Auto-generated catch block
  37. e.printStackTrace();
  38. } catch (IOException e) {
  39. // TODO Auto-generated catch block
  40. e.printStackTrace();
  41. }
  42. break;

  43. }
  44. super.onCallStateChanged(state, incomingNumber);
  45. }
  46. }
   [5] 加权限
 
   
  1. <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  2. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
   [6]把开启服务的逻辑放到手机重启的广播中
 
   
  1. package com.phone.phonelistener;

  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;

  5. public class BootReceiver extends BroadcastReceiver {

  6. @Override
  7. public void onReceive(Context context, Intent intent) {
  8. //服务开启
  9. Intent intent1 = new Intent(context,PhoneService.class);
  10. context.startService(intent1);
  11. }

  12. }
 
    
  1. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
 
     
  1. <application
  2. android:allowBackup="true"
  3. android:icon="@drawable/ic_launcher"
  4. android:label="@string/app_name"
  5. android:theme="@style/AppTheme" >
  6. <activity
  7. android:name=".MainActivity"
  8. android:label="@string/app_name" >
  9. <!-- <intent-filter>
  10. <action android:name="android.intent.action.MAIN" />

  11. <category android:name="android.intent.category.LAUNCHER" />
  12. </intent-filter> -->
  13. </activity>
  14. <service android:name="com.phone.phonelistener.PhoneService"></service>
  15. <receiver android:name="com.phone.phonelistener.BootReceiver">
  16. <intent-filter >
  17. <action android:name="android.intent.action.BOOT_COMPLETED"/>
  18. </intent-filter>
  19. </receiver>
  20. </application>
4    使用服务注册特殊的广播接收者
    操作特别频繁的广播事件    比如屏幕的解锁和锁屏
    实现步骤
    [1]定义广播接收者    接收屏幕解锁屏幕的事件
 
   
  1. package com.phone.registerbroadcast;

  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;

  5. public class ScreenReceiver extends BroadcastReceiver {

  6. @Override
  7. public void onReceive(Context context, Intent intent) {
  8. //获取当前事件类型
  9. String action = intent.getAction();
  10. if("android.intent.action.SCREEN_OFF".equals(action)){
  11. System.out.println("说明屏幕锁屏了");
  12. }else if("android.intent.action.SCREEN_ON".equals(action)){
  13. System.out.println("说明屏幕解屏了");
  14. }
  15. }

  16. }
    [2]写一个服务    用来注册广播接收者
 
   
  1. package com.phone.registerbroadcast;

  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.content.IntentFilter;
  5. import android.os.IBinder;

  6. public class ScreenService extends Service {

  7. private ScreenReceiver receiver;
  8. @Override
  9. public IBinder onBind(Intent intent) {
  10. // TODO Auto-generated method stub
  11. return null;
  12. }
  13. @Override
  14. public void onCreate() {
  15. //[1]创建ScreenReceiver实例
  16. receiver = new ScreenReceiver();
  17. //[2]获取IntentFilter 实例 目的是添加action
  18. IntentFilter filter = new IntentFilter();
  19. //[3]动态添加action
  20. filter.addAction("android.intent.action.SCREEN_OFF");
  21. filter.addAction("android.intent.action.SCREEN_ON");
  22. //[4]注册服务
  23. registerReceiver(receiver, filter);
  24. super.onCreate();
  25. }
  26. @Override
  27. public void onDestroy() {
  28. unregisterReceiver(receiver);
  29. super.onDestroy();
  30. }

  31. }
    [3]在MainActivity的onCreate方法中开启服务
 
   
  1. package com.phone.registerbroadcast;

  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.os.Bundle;


  5. public class MainActivity extends Activity {


  6. @Override
  7. protected void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.activity_main);
  10. Intent intent = new Intent(this,ScreenReceiver.class);
  11. startService(intent);
  12. }
  13. }
    [4]配置服务
 
   
  1. <service android:name="com.phone.registerbroadcast.ScreenService"></service>
5    bindService开启服务
    [1]第一次点击按钮 会执行服务的onCreate方法和onBind方法
    [2]当onBind方法返回null的时候onServiceConnected方法是不执行的
    [3]第二次点击按钮    服务没有响应
    [4] 不求同时生 但求同时死    指的是调用者和服务之间
    [5]服务不可以多次解绑    多次解绑会报异常
    [6]通过bind方式开启服务    服务不能在设置页面找到    相当于是一个隐形的服务
6    为什么要引入bindService
    目的是为了调用服务里的方法
7    通过bindservice方式调用 服务方法里面的过程
    [1]在服务的内部定义一个方法    让activity调用
    [2]在服务的内容定义一个中间人对象(IBinder)
    [3]把定义的中间人对象在onBind方法里面返回
    [4]在mainactivity的oncreate方法里面调用bindservice的目的是为了获取我们定义的中间人对象
    [5]获取中间人对象
    [6]拿到中间人对象就可以间接调用到服务里面的方法
    [7]当Activity销毁的时候解绑服务
 
   
  1. package com.phone.ban;

  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.Binder;
  5. import android.os.IBinder;
  6. import android.widget.Toast;

  7. public class BanZhangService extends Service {
  8. //把定义的中间人对象返回
  9. @Override
  10. public IBinder onBind(Intent intent) {
  11. return new MyBinder();
  12. }

  13. public void banZhang(int money) {
  14. if(money > 1000){
  15. Toast.makeText(getApplicationContext(), "我是领导 把证给你办了", 1).show();
  16. }else{
  17. Toast.makeText(getApplicationContext(), "这点钱还想办事....", 1).show();
  18. }
  19. }
  20. //[1]定义中间人对象
  21. public class MyBinder extends Binder{
  22. public void callBanZheng(int money){
  23. //调用办证方法
  24. banZhang(money);
  25. }
  26. }

  27. }
 
    
  1. package com.phone.ban;

  2. import android.app.Activity;
  3. import android.content.ComponentName;
  4. import android.content.Intent;
  5. import android.content.ServiceConnection;
  6. import android.os.Bundle;
  7. import android.os.IBinder;
  8. import android.view.View;

  9. import com.phone.ban.BanZhangService.MyBinder;


  10. public class MainActivity extends Activity {
  11. private MyConn conn;
  12. private MyBinder myBinder;//定义的中间人对象
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. Intent intent = new Intent(this,BanZhangService.class);
  18. //绑定服务
  19. conn = new MyConn();
  20. bindService(intent, conn, BIND_AUTO_CREATE);
  21. }
  22. //点击按钮调用服务里办证的方法
  23. public void click(View v){
  24. myBinder.callBanZheng(1001);
  25. }
  26. //监视服务的状态
  27. private class MyConn implements ServiceConnection{


  28. //当服务连接成功调用
  29. @Override
  30. public void onServiceConnected(ComponentName name, IBinder service) {
  31. myBinder = (MyBinder) service;
  32. }

  33. @Override
  34. public void onServiceDisconnected(ComponentName name) {
  35. }
  36. }
  37. @Override
  38. protected void onDestroy() {
  39. //当activity销毁的时候解绑服务
  40. unbindService(conn);
  41. super.onDestroy();
  42. }


  43. }
8    通过接口方式调用服务里面的方法
    接口可以隐藏代码内部的细节    让程序员暴露自己只想暴露的方法
    [1]定义一个接口    把想暴露的方法都定义在接口里面
    [2]我们定义的中间人对象事项我们自己定义的接口
    [3]在获取中间人对象的时候
 
   
  1. myBinder = (Iservice) service;
补充:混合方式开启服务
    需求:既想让服务在后台长期运行    又想调用服务里面的方法
    [1]先调用startService方法开启服务    能够保证服务在后台长期运行
    [2]调用bindService方法    去获取中间人对象
    [3]调用unbindSerivce    解绑服务
    [4]调用stopSerivce
9    百度音乐盒框架
 
   
  1. package com.phone.baidumusic;

  2. import android.content.ComponentName;
  3. import android.content.Intent;
  4. import android.content.ServiceConnection;
  5. import android.os.Bundle;
  6. import android.os.IBinder;
  7. import android.app.Activity;
  8. import android.view.View;


  9. public class MainActivity extends Activity {
  10. //中间人对象
  11. private IService iService;
  12. private MyConn conn;
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. //混合方式开启服务
  18. //[1]先调用startservice 目的是可以保证服务在后台长期运行
  19. Intent intent = new Intent(this, MusicService.class);
  20. startService(intent);
  21. //[2]调用bindservice 目的为了获取我们定义的中间人对象 就可以间接的调用服务里面的方法了
  22. conn = new MyConn();
  23. bindService(intent, conn, BIND_AUTO_CREATE);
  24. }
  25. @Override
  26. protected void onDestroy() {
  27. //当Activity销毁的时候 解绑服务
  28. unbindService(conn);
  29. super.onDestroy();
  30. }
  31. //点击按钮 播放音乐
  32. public void click1(View v){
  33. iService.callPlayMusic();
  34. }
  35. //点击按钮 暂停音乐
  36. public void click2(View v){
  37. iService.callPauseMusic();
  38. }
  39. //点击按钮 继续播放音乐
  40. public void click3(View v){
  41. iService.callRePlayMusic();
  42. }
  43. //监听服务的状态
  44. private class MyConn implements ServiceConnection{

  45. @Override
  46. public void onServiceConnected(ComponentName name, IBinder service) {
  47. iService = (IService) service;
  48. }

  49. @Override
  50. public void onServiceDisconnected(ComponentName name) {
  51. }
  52. }
  53. }
 
    
  1. package com.phone.baidumusic;

  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.Binder;
  5. import android.os.IBinder;
  6. import android.view.View;

  7. public class MusicService extends Service {

  8. @Override
  9. public IBinder onBind(Intent intent) {
  10. return new MyBinder();
  11. }

  12. @Override
  13. public void onCreate() {
  14. super.onCreate();
  15. }

  16. @Override
  17. public void onDestroy() {
  18. super.onDestroy();
  19. }

  20. // 播放音乐
  21. public void playMusic() {
  22. // TODO 等讲完多媒体 再完善该案例
  23. System.out.println("音乐播放了");
  24. }

  25. // 暂停音乐
  26. public void pauseMusic() {
  27. // TODO 等讲完多媒体 再完善该案例
  28. System.out.println("音乐暂停了");
  29. }

  30. // 继续播放音乐
  31. public void rePlayMusic() {
  32. // TODO 等讲完多媒体 再完善该案例
  33. System.out.println("音乐继续播放了");
  34. }

  35. // [1]在服务的内部定义一个中间对象(IBinder)
  36. private class MyBinder extends Binder implements IService{

  37. @Override
  38. public void callPlayMusic() {
  39. playMusic();
  40. }

  41. @Override
  42. public void callPauseMusic() {
  43. pauseMusic();
  44. }

  45. @Override
  46. public void callRePlayMusic() {
  47. rePlayMusic();
  48. }

  49. }
  50. }
 
     
  1. package com.phone.baidumusic;


  2. public interface IService {
  3. public void callPlayMusic();
  4. public void callPauseMusic();
  5. public void callRePlayMusic();
  6. }
 
      
  1. <service android:name="com.phone.baidumusic.MusicService"></service>
10    aidl介绍
    本地服务:运行自己应用里面的服务
    远程服务:运行在其他应用里面的服务
    实现进程间通信    IPC
    aidl:Android Interface defined Language    安卓接口定义语言
            专门是用来解决进程间通信的
    
    总结:使用aidl的步骤
   [1]把IService.java文件变成一个aidl文件
   [2]adil这个语言不认识public 把public去掉
   [3]自动生成一个IService.java文件 系统自动帮助我们生成一个类Stub(在gen目录下)
   [4]我们自己定义的中间人对象直接继承Stub
   [5]保证2应用的aidl文件是同一个    保证aidl文件所在的包名相同
   [6]获取中间人对象的方式不一样了
    IService  = Stub.asInterface(service);
11    aidl的应用场景
    比如    支付宝

转载于:https://www.cnblogs.com/phonecom/p/6218440.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值