zoukankan      html  css  js  c++  java
  • android 学习随笔十七(服务 )

    1、Service

    • 四大组件之一
    • 运行于后台,没有前台界面的组件,用于运行需要在后台运行的代码
    • 可以理解为没有前台的Activity
    • 定义方式:创建java类继承Service,清单文件中注册该类
    • package com.ecollab.runservice;
      
      import android.app.Service;
      import android.content.Intent;
      import android.os.IBinder;
      
      public class MyService extends Service {
      
          @Override
          public IBinder onBind(Intent intent) {
              return null;
          }
      
          @Override
          public void onCreate() {
              super.onCreate();
          }
      
          @Override
          public int onStartCommand(Intent intent, int flags, int startId) {
              return super.onStartCommand(intent, flags, startId);
          }
      
          @Override
          public void onDestroy() {
              super.onDestroy();
          }
      
      }
      View Code
    • 清单文件中注册:<service name="com.ecollab.runservice.MyService"/>

    2、服务的启动和生命周期

    • 用户手动停止服务,服务不会重启,但是如果被自动关闭,内存充足就会重启
    • startService的生命周期
      • onCreate->onStartCommand->onDestroy
      • 重复的startService不会调用onCreate只会重复调用onStartCommand

    public void start(View v) {
    //启动服务,显示启动服务
    Intent service = new Intent(this,MyService.class);
    startService(service);
    }

    public void stop(View v) {
    //停止服务
    Intent service = new Intent(this,MyService.class);
    stopService(service);
    }

    3、进程优先级

    1. 前台进程:拥有一个正在与用户交互的Activity(onResume方法调用)
    2. 可见进程:拥有一个不在前台但是对用户依然可见的Activity(onPause方法调用)
    3. 服务进程:拥有一个通过startService启动的服务
    4. 后台进程:拥有一个对于用户不可见的Activity(onStop方法调用)
    5. 空进程:没有任何活动的应用组件(Activity和Service)

    4、电话录音

    • 创建服务:
    package com.ecollab.runservice;
    
    import android.app.Service;
    import android.content.Intent;
    import android.media.MediaRecorder;
    import android.os.IBinder;
    import android.telephony.PhoneStateListener;
    import android.telephony.TelephonyManager;
    
    public class RecordService extends Service {
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            //获取电话管理器
            TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
            //监听电话状态
            tm.listen(new MyListener(), PhoneStateListener.LISTEN_CALL_STATE);
        }
    
        class MyListener 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.release();
                        recorder = null;
                    }
                    break;
                case TelephonyManager.CALL_STATE_RINGING:
                    recorder = new MediaRecorder();
                    //设置声音来源
                    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                    //设置音频文件格式
                    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                    recorder.setOutputFile("sdcard/haha.3gp");
                    //设置音频文件编码
                    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                    try {
                        recorder.prepare();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    if(recorder != null){
                        recorder.start();
                    }
                    break;
                default:
                    break;
                }
            }
        }
    }
    RecorderService
    • 权限:

    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>

    • 注册:

    <service android:name="com.ecollab.runservice.RecordService"></service>

    • 启动服务:

    public void startrecord(View v) {
    //启动录音机
    Intent service = new Intent(this,RecordService.class);
    startService(service);
    }

    5、服务两种启动方式

    • startService

    * 开始服务,会使进程变成为服务进程
    * 启动服务的activity和服务不再有关系

    • bindService

    * 绑定服务不会使进程变成服务进程,通过bindService启动的服务,进程优先级不变
    * 绑定服务,是activity与服务建立连接,如果activity销毁了,服务也会被解绑并销毁,但是如果服务被销毁,activity不会被销毁。不能做后台操作
    * 绑定服务和解绑服务的生命周期方法:onCreate->onBind->onUnbind->onDestroy

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    conn = new MyConn();
    }


    public void start(View v){
    Intent intent = new Intent(this, MyService.class);
    startService(intent);
    }
    public void stop(View v){
    Intent intent = new Intent(this, MyService.class);
    stopService(intent);
    }
    public void bind(View v){
    Intent intent = new Intent(this, MyService.class);
    //绑定服务
    bindService(intent, conn, BIND_AUTO_CREATE);
    }

    public void unbind(View v){
    //解绑服务
    unbindService(conn);
    }

    class MyConn implements ServiceConnection{

    //到服务的连接被建立了,此方法调用
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
    // TODO Auto-generated method stub

    }

    //到服务的连接中断了,此方法调用
    @Override
    public void onServiceDisconnected(ComponentName name) {
    // TODO Auto-generated method stub

    }

    }
    }

    6、调用服务方法

     不能直接调用服务中的方法, 可通过中间组件调用服务中的方法。

    ---------------------------------------------------------------------------------------------------

    package com.itheima.leaderservice;

    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;

    public class LeaderService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
    // 返回中间人对象
    return new FengMiShu();
    }

    class FengMiShu extends Binder implements PublicBusiness{
    //中间人的牵线
    @Override
    public void qianXian(){
    //调用领导的办证
    banZheng();
    }

    public void takeSoap(){

    }
    }

    public void banZheng(){
    System.out.println("成功办证");
    }
    }

    --------------------------------------------------------------------------------------------

    package com.itheima.leaderservice;//定义接口为了:只有接口中的方法才允许被调用

    public interface PublicBusiness {

    void qianXian();
    }

    --------------------------------------------------------------------------------------------

    public class MainActivity extends Activity {

    // FengMiShu fms;
    PublicBusiness pb;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Intent intent = new Intent(this, LeaderService.class);
    bindService(intent, new ServiceConnection() {//不解除服务,可以直接newServiceConnection,如果要解除服务必须定义class MyConn implements ServiceConnection

    //连接因为异常而终止才会调用
    @Override
    public void onServiceDisconnected(ComponentName name) {

    }

    //onBind有返回值此方法才会调用
    //service:这个对象就是onBind返回的中间人
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
    pb = (PublicBusiness) service;

    }
    }, BIND_AUTO_CREATE);
    }


    public void click(View v){
    pb.qianXian();
    }

    }

     7、混合启动

    为了避免用bindService启动服务后,当activity销毁时,服务也被销毁,可以用混合启动,保证当activity销毁时,服务依然在运行

    混合启动:先startService(intent);再bindService(intent, 

    startService(intent);

    bindService(intent, ..............................解绑后不会摧毁服务,只有停止服务才会摧毁服务

    服务的混合启动及摧毁顺序:start-bind-unbind-stop

    消息

  • 相关阅读:
    sql 查出一张表中重复的所有记录数据
    几种常见SQL分页方式效率比较
    Redis命令参考之复制(Replication)
    Redis-benchmark使用总结
    redis压力测试详解
    c#:ThreadPool实现并行分析,并实现线程同步结束
    C#多线程学习 之 线程池[ThreadPool]
    [C#基础]ref和out的区别
    C#:ref和out的联系及区别。
    生产环境中使用Docker Swarm的一些建议
  • 原文地址:https://www.cnblogs.com/ecollab/p/5910424.html
Copyright © 2011-2022 走看看