Service学习笔记

1.Service生命周期以及绑定本地服务

在这里插入图片描述

onCreate() : 在该Service第一次被创建的时候被调用
onBind() : 该方法是Service子类必须实现的一个方法,该方法返回一个IBinder对象,应用程序通过该对象与Service进行通信。
onDestroy() : 该Service被关闭之前被调用
onStartCommand() :每次客户端调用startService(intent)的方法启动时都会调用。
onUnbind(Intent intent) ;接绑时调用
代码如下:

  <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"></service>

MainActivity

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
   private TextView getText;
   private Button get;
   private Button start;
   private Button stop;
   private Button bind;
   private Button unbind;
   private MyService.MyBinder binder;

   private ServiceConnection conn = new ServiceConnection() {
       @Override
       public void onServiceConnected(ComponentName name, IBinder service) {
           binder = (MyService.MyBinder)service;
       }

       @Override
       public void onServiceDisconnected(ComponentName name) {
           binder = null;
       }
   };

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

   @Override
   public void onClick(View v) {
       switch (v.getId()){
           case R.id.start :
               startService(new Intent(this,MyService.class));
               break;
           case R.id.stop :
               stopService(new Intent(this,MyService.class));
               break;
           case R.id.bind :
               bindService(new Intent(this,MyService.class),conn, Service.BIND_AUTO_CREATE);
               break;
           case R.id.unbind :
               unbindService(conn);
               break;
           case R.id.get :
               getText.setText(""+binder.getCount());
               break;
       }

   }
   private void init(){
       getText = (TextView)findViewById(R.id.get_text);
       start = (Button)findViewById(R.id.start);
       stop = (Button)findViewById(R.id.stop);
       bind = (Button)findViewById(R.id.bind);
       unbind = (Button)findViewById(R.id.unbind);
       get = (Button)findViewById(R.id.get);

       start.setOnClickListener(this);
       stop.setOnClickListener(this);
       bind.setOnClickListener(this);
       unbind.setOnClickListener(this);
       get.setOnClickListener(this);
   }
}

MyService

public class MyService extends Service {
    private static final String TAG = "haha";
    private MyBinder mBinder = new MyBinder();
    public MyService() {
    }
    class MyBinder extends Binder{
        public int getCount(){
            return 2;
        }
    }
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind: ");
        // TODO: Return the communication channel to the service.
       return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate: ");
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.d(TAG, "onStart: ");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand: ");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy: ");
        super.onDestroy();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "onUnbind: ");
        return super.onUnbind(intent);
    }
}

startService()启动Service:
在这里插入图片描述
stopService停止Service:
在这里插入图片描述
bindService绑定本地服务:
在这里插入图片描述
unbindService解绑服务;
在这里插入图片描述

2.IntentService

Service本身存在的两个问题:
(1)不会专门启动一个单独的进程,Service与它所在的应用在同一进程中。
(2)不是一个新的线程,因此不应该在Service中直接进行耗时的操作。
IntentService的特征:
(1)IntentService会创建单独的work线程来处理所有的Intent请求。
(2)IntentService会创建单独的work线程来处理onHandleIntent()方法实现的代码,因此开发者无需处理多线程的问题。
(3)当请求处理完成后,IntentService会自动停止,因此开发者无需调用stopSelf()方法来停止该Service
(4)为Service的onBind()方法提供了默认实现,默认实现的onBind()方法返回null.。
(5)为Service的onStartCommand()提供了默认的实现,该实现会将请求的Intent添加到队列中。
综上所述:扩展IntentService实现Service无需重写onBind,onStartCommand(),只需要重写onHandleIntent()方法即可。
在这里插入图片描述
工作流程:

客户端通过startService(Intent)来启动IntentService; 我们并不需要手动地区控制IntentService,当任务执行完后,IntentService会自动停止; 可以启动IntentService多次,每个耗时操作会以工作队列的方式在IntentService的 onHandleIntent回调方法中执行,并且每次只会执行一个工作线程,执行完一,再到二这样!

3.Activity与Service通信

基本流程如下:
1.自定义Service中,自定义一个Binder类,然后将需要暴露的方法都写到该类中!
2.Service类中,实例化这个自定义Binder类,然后重写onBind()方法,将这个Binder对象返回!
3.Activity类中实例化一个ServiceConnection对象,重写onServiceConnected()方法,然后 获取Binder对象,然后调用相关方法即可!
MyService

    public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return new MyBinder();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return super.onStartCommand(intent, flags, startId);
    }
    static class MyBinder extends Binder{
        public int getNumber(){
            return 520;
        }
    }
}

MainActivity :

public class MainActivity extends AppCompatActivity {
    private MyService.MyBinder myBinder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this,MyService.class);
        bindService(intent,serviceConnection,BIND_AUTO_CREATE);
    }
    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myBinder = (MyService.MyBinder)service;
            Log.d("TAG", "onServiceConnected: "+myBinder.getNumber());
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
}

4. 简单定时后台线程的实现

Android中给我们提供的定时方式有两种使用Timer类与Alarm机制!前者不适合于需要长期在后台运行的定时任务,CPU一旦休眠,Timer中的定时任务 就无法运行;Alarm则不存在这种情况,他具有唤醒CPU的功能,另外,也要区分CPU 唤醒与屏幕唤醒!
使用流程:

    Step 1:获得Service: AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
    Step 2:通过set方法设置定时任务 int anHour = 2 * 1000; long triggerAtTime = SystemClock.elapsedRealtime() + anHour; manager.set(AlarmManager.RTC_WAKEUP,triggerAtTime,pendingIntent);
    Step 3:定义一个Service 在onStartCommand中开辟一条事务线程,用于处理一些定时逻辑
    Step 4:定义一个Broadcast(广播),用于启动Service 最后别忘了,在AndroidManifest.xml中对这Service与Boradcast进行注册!

参数详解: set(int type,long startTime,PendingIntent pi)

①type: 有五个可选值:
AlarmManager.ELAPSED_REALTIME: 闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3;
AlarmManager.ELAPSED_REALTIME_WAKEUP 闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间,状态值为2;
AlarmManager.RTC 闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间,状态值为1;
AlarmManager.RTC_WAKEUP 表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间,状态值为0;
AlarmManager.POWER_OFF_WAKEUP 表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一, 该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值