Android Service 相关

前言

Service是四大组件中的一员,它属于逻辑计算型的组件,往往在后台做逻辑处理。本文整理了Service相关的知识点:


startService

1.创建Service,写一个类继承Service,重写onCreate,onStartCommond,onBind方法,在AndroidManifest.xml文件里配置。

2.启动Service,使用Intent启动,如下:

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

3.第一次startService(),执行方法顺序:

onCreate->onStartCommond

之后无论再次startService(),只会执行onStartCommond方法,也就是onCreate只执行一次。

4.销毁Service:调用stopService()即可。


bindService

当我们需要Service和Activity进行通讯的时候,就可以将Activity和Service绑定。

1.关联Service,代码如下:

MyService

public class MyService extends Service {

    public static final String TAG = "MyService";

    private MyBinder mBinder = new MyBinder();

    @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();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    class MyBinder extends Binder {

        public void down() {
            Log.d("TAG", "down");
        }

    }

}
private ServiceConnection connection = new ServiceConnection() {  

        @Override  
        public void onServiceDisconnected(ComponentName name) {  
        }  

        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) {  
            myBinder = (MyService.MyBinder) service;  
            myBinder.down();//调用onBind()里的方法 
        }  
    };


Intent bindIntent = new Intent(this, MyService.class);  
            bindService(bindIntent, connection, BIND_AUTO_CREATE); 

这里我们首先创建了一个ServiceConnection的匿名类,在里面重写了onServiceConnected()方法和onServiceDisconnected()方法,这两个方法分别会在Activity与Service建立关联和解除关联的时候调用。在onServiceConnected()方法中,我们又通过向下转型得到了MyBinder的实例,有了这个实例,Activity和Service之间的关系就变得非常紧密了。现在我们可以在Activity中根据具体的场景来调用MyBinder中的任何public方法,即实现了Activity指挥Service干什么Service就去干什么的功能。bindService需要传入三个参数,第一个参数就是刚刚构建出的Intent对象,第二个参数是前面创建出的ServiceConnection的实例,第三个参数是一个标志位,这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service,这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行。

2.解绑Service:调用unBindService()即可。

3.销毁Service:由于在关联Service的时候指定的标志位是BIND_AUTO_CREATE,说明点击Bind Service按钮的时候Service也会被创建。如果只调用stopService和unbindService中的一个是无法销毁的,必须是两个方法都调用,解释如下:

stopService只会让Service停止,unbindService只会让Service和Activity解除关联,一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁。

前台Service

Service一般都是在后台运行的,但是后台Service的优先级比较低,在系统内存不足的时候,很可能被系统Kill掉。如果我们想要提高Service的优先级,不妨使用前台Service。前台Service在通知栏会一直有显示,如墨迹天气。使用如下:

 @Override  
    public void onCreate() {  
        super.onCreate();  
        Notification notification = new Notification(R.drawable.ic_launcher,  
                "有通知到来", System.currentTimeMillis());  
        Intent notificationIntent = new Intent(this, MainActivity.class);  
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,  
                notificationIntent, 0);  
        notification.setLatestEventInfo(this, "这是通知的标题", "这是通知的内容",  
                pendingIntent);  
        startForeground(1, notification);  
        Log.d(TAG, "onCreate()");  
    }  

我们首先创建了一个Notification对象,然后调用了它的setLatestEventInfo()方法来为通知初始化布局和数据,并在这里设置了点击通知后就打开MainActivity。然后调用startForeground()方法就可以让MyService变成一个前台Service,并会将通知的图片显示出来。


Service与Thread

1.初学Android的时候,我也会问‘Service和Thread到底什么关系?’,其实这两者是完全没有关系的。我们需要理解,Android的后台就是指,它的运行是完全不依赖UI的。即使Activity被销毁,或者程序被关闭,只要进程还在,Service就可以继续运行。

2.Service是运行在主线程的,我们可以通过如下代码证实:

MainActivity的onCreate()方法

Log.e("MainActivity", "MainActivity thread id is " + Thread.currentThread().getId());

MyService的onCreate()方法

Log.E("MyService", "MyService thread id is " + Thread.currentThread().getId());  

我们会发现,打印出来的值是一样的。也就是我们在Service里不要做耗时操作,反之同样会出现“ANR”。


远程Service

在上面,我们提到,如果在Service里做耗时操作会导致’ANR’,那么我们只需要另起线程去做耗时任务即可。当然也可以使用IntentService,参照我的另一篇博文Android IntentService详解。下面来看看远程Service,用法很简单,如下:

    <service  
        android:name="com.example.servicetest.MyService"  
        android:process=":remote" >  
    </service>  

我们只需要在配置文件里为Service配置process属性即可。此时,我们在Service里做耗时操作,并不会’ANR’了。原因是我们的Service现在已经处于另一个进程了,它只会阻塞该进程中的主线程,并不会影响到我们的主程序。

1.此时的Service,如果我们直接调用bindService,那么就会直接崩溃。原因是我们的Activity和Service已经处于不同的进程里,按照之前的方式是无法建立关联了。

2.如需跨进程让Service和Activity关联。则需要使用到跨进程通讯Aidl。这个会在我的另一篇文章进行整理。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值