Android知识梳理之Service整理

          PS.不知不觉间发现自己已经做了很久很久的Android开发了,过去对知识块的梳理总是放在云笔记里面.主要的原因还是自己的笔记太杂乱,没有脉络.本着开源的精神,也趁着这段时间有空将之前云笔记里面的文章梳理下.同时将一些知识点整理出来和大家共同分享.转载请注明出处:http://blog.csdn.net/unreliable_narrator?viewmode=contents                                                                                        

一.服务的概念.           

service就是就是一个没有界面的activity,同属于四大组件之一,使用的时候需要在清单文件中进行配置.service的主要作用就是在后台做一些比较耗时的操作.例如访问网络,后台播放,进行复杂计算等等.一般只要是满足于两个条件就可以使用service了,一是没有界面的交互,二是在后台长时间的运行,services实际上也是运行在ui线程里面的,所以一些比较耗时的操作不要直接写在services里面,而是应该在services再重新开启一个线程来进行耗时的操作.

二.启动方式(三种).

  1.Context.startService()方式启动

    1.1 代码

Intent startIntent = new Intent(MainActivity.this, MyService.class);
startService(startIntent);

 

public class MyService extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d("++", "MyService_onBind");
        return null;
    }

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

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("++", "MyService_onCreate");

    }

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

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

 

  1.2说明:

    直接通过context.startservice()方法来开启服务,这种方式开启的服务,服务会一直在后台运行,可以通过context.stopservice()来将服务进行关闭.如果程序关闭的时候没有将service关闭,那么service还是会继续在后台进行默默的运行.也就是说这种方式开启的服务是和调用者没有任何关系的.如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStartCommand()方法。     

这种方式开启的服务,服务会一直在后台运行,可以通过context.stopservice()来将服务进行关闭.如果程序关闭的时候没有将service关闭,那么service还是会继续在后台进行默默的运行.也就是说这种方式开启的服务是和调用者没有任何关系的.

    1.3停止服务

  1. 在外部使用stopService()手动停止。
  2. 在服务内部(onStartCommand方法内部)使用stopSelf()方法,使服务执行完毕后自动停止。比如说,一个start的Service执行在后台下载或上传一个文件的操作,完成之后,Service应自己停止。

     1.4生命周期:

启动时startService –> onCreate() –> onStart()

停止时 stopService –> onDestroy()

在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService(startIntent)方法前服务已经被创建,多次调用startService(startIntent)方法并不会导致多次创建服务,但会导致多次调用onStart()方法。

    2.通过Context.bindService()方法来开启服务

      2.1.代码实现。

public class MainActivity extends AppCompatActivity {
    private MyService mMyService;
    public class MyConn implements ServiceConnection {

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mMyService = (MyService.MyBinder) service;
        mMyService.doOnServices();//调用服务里的方法.
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
    }
}
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this,MyService.class);
        bindService(intent,myConn,BIND_AUTO_CREATE);//绑定服务.
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(myConn);
    }

 

public class MyService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        MyBinder myBinder = new MyBinder();
        Log.d("MyService", "MyService_onBind");
        return myBinder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        Log.d("MyService", "MyService_onUnbind");
        return super.onUnbind(intent);
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService", "MyService_onCreate");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MyService", "MyService_onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyService", "MyService_onDestroy");
    }
    /*binder对象
    * */
    public class MyBinder extends Binder {
        public void doBinder() {
            doSMinServices();
        }
    }
    /*
    * 服务里面的方法
    * */
    public void doOnServices() {
        Toast.makeText(MyService.this, "我是服务中的方法,我被调用了", Toast.LENGTH_SHORT).show();
    }
}

 

       2.2 定义

许多的时候我们不但要将服务开启还要调用服务里面的方法,这时候我们就需要使用绑定服务的方式来开启服务了.通过绑定方式开启的服务如果服务的调用者被关闭了,那么服务也会被关闭.需要注意的是任何一个Service在整个应用程序范围内都是通用的,即MyService不仅可以和MainActivity建立关联,还可以和任何一个Activity建立关联,而且在建立关联时它们都可以获取到相同的MyBinder实例。     

      2.3生命周期:

  • 绑定时,bindService -> onCreate() –> onBind();
  • 调用者退出了,即解绑定时,Srevice就会unbindService –>onUnbind() –> onDestory();

      2.4注意事项:

1、onCreate()、onBind()方法只会在Service第一次被创建的时候调用,多次点击绑定启动不会执行任何方法,onUnbind()、onDestroy()方法会在调用者执行unbindService()方法时执行或者Activity退出时自动执行。

2、如果我们既通过startService()开启Service,又用通过bindService开启,必要unbindService()和stopService()都执行一次(没有先后顺序),Service才会被销毁。

3、如果多次执行unbinsService()方法,程序会异常退出,我们需要在代码中加一个判断是否绑定的标记mBound来解决此问题。

      2.5绑定服务和普通开启服务的区别:

  • 绑定服务是和他的调用者的生命周期相关的,也就是说当调用者被销毁的时候,绑定服务也会同时被销毁.普通服务的生命周期和他的调用者是没有关系的,也就是说当调用者被关闭的时候服务仍旧是会在后台进行.而不会被销毁.
  • 绑定服务是在任务管理器里面不可以看到的.普通服务是可以在任务管理器里面看到的.
  • 开启普通服务的调用者是没有办法调用服务里面的相关的方法的.通过绑定服务就可以直接调用服务中的方法.

3.混合开启服务

  3.1代码.

public class MainActivity extends AppCompatActivity {
    private MyService mMyService;
    public class MyConn implements ServiceConnection {

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mMyService = (MyService.MyBinder) service;
        mMyService.doOnServices();//调用服务里的方法.
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
    }
}
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this,MyService.class);
        bindService(intent,myConn,BIND_AUTO_CREATE);//绑定服务.
        startService(intent);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(myConn);
    }

3.2定义.

很多时候我们开启服务以后,不但要调用服务的方法还需要服务一直在后台继续执行,也就是要兼具以上二者的优势,所以需要使用到混合开启服务.

  • 通过startService()方式开启服务(只能通过调用stopService停止)
  • 通过bindService进行绑定,以进行服务的方法调用(当需要的时候)
  • 通过unbindService进行解绑(不需要调用方法了,在UI线程被销毁之前解绑)
  • 通过stopService停止服务

3.3注意事项:

    1.如果先startService(),再bindService(): 在bind的Activity退出且调用unbindService(myConn)的时候,Service会执行unBind方法而不执行其onDestory方法,因为有startService方法调用过,所以Activity与Service解除绑定后,还是会有一个与调用者没有关连的Service存在。

    2.如果先bindService(),再startService(),再调用Context.stopService(), Service的onDestory方法不会立刻执行,因为有一个与Service绑定的Activity,但是在Activity退出的时候,会执行其(Service的)onDestory方法,如果要立刻执行stopService,就得先解除绑定。

     3.如果先是bindService(),那么startService()的时候就直接运行Service的onStartCommand()方法,如果先是startService(),那么bindService()的时候就直接运行onBind()方法。

      4.当一个服务没被onDestory()销毁之前,只有第一个启动它的客户端能调用它的onBind()和onUnbind()。

 

二.提高服务的优先级.

        方式一:使用notification来使得服务的的优先级扩大.在服务的oncreate()或者是onstartcommed()方法里面调用开启服务.

public class MyService extends Service {
    ...
    @Override
    public void onCreate() {
        super.onCreate();
        //创建通知对象
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentText("测试代码");
        builder.setSmallIcon(R.drawable.biaoqin);
        Notification build = builder.build();
        //调用此方法将通知和服务绑定在一起
        startForeground(1, build);
    }
}

方式二:在清单文件里面通过对服务的属性进行设置来提高服务的优先级.

<!-- 为了消去加上android:priority="1000"后出现的警告信息,可以设置android:exported属性,指示该服务是否能够被其他应用程序组件调用或跟它交互 -->

<service android:name="com.example.helloandroid.weatherforecast.service.UpdateWidgetService"android:exported="false" >

<!-- 为防止Service被系统回收,可以通过提高优先级解决,1000是最高优先级,数字越小,优先级越低 -->

<intent-filter android:priority="1000"></intent-filter>

</service>

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值