Service

作者: jacky123 | 来源:发表于2016-07-25 22:39 被阅读35次

    Service的生命周期

    public class MyService extends Service {
    
        public static final String TAG = "MyService";
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.d(TAG, "onCreate() executed");
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.d(TAG, "onStartCommand() executed");
            return super.onStartCommand(intent, flags, startId);
        }
        
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.d(TAG, "onDestroy() executed");
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
    }
    

    第一次点击Start Service



    之后点击


    onCreate()方法只会在Service第一次被创建的时候调用,如果当前Service已经被创建过了,不管怎样调用startService()方法,onCreate()方法都不会再执行。

    因此你可以再多点击几次Start Service按钮试一次,每次都只会有onStartCommand()方法中的打印日志。
    点击一下Stop Service按钮就可以将Service停止掉了。


    Service和Thread的关系

    Service和Thread之间没有任何关系。
    之所以有不少人会把它们联系起来,主要就是因为Service的后台概念。Thread我们大家都知道,是用于开启一个子线程,在这里去执行一些耗时操作就不会阻塞主线程的运行。而Service我们最初理解的时候,总会觉得它是用来处理一些后台任务的,一些比较耗时的操作也可以放在这里运行,这就会让人产生混淆了。但是,如果我告诉你Service其实是运行在主线程里的。所以Service的onCreate方法中是不能执行耗时操作的,如果有就会ANR。

    //在MainActivity的onCreate()方法里加入一行打印当前线程id的语句:
    Log.d("MyService", "MainActivity thread id is " + Thread.currentThread().getId());
    
    //MyService的onCreate()方法里也加入一行打印当前线程id的语句
    Log.d("MyService", "MyService thread id is " + Thread.currentThread().getId());
    

    一般会在Service里创建一个子线程,那为什么不直接在Activity里创建呢?这是因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。


    启动前台Service

    public class MyService extends Service {
    
        public static final String TAG = "MyService";
    
        private MyBinder mBinder = new MyBinder();
    
        @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() executed");
        }
    
        .........
    
    }
    

    这里只是修改了MyService中onCreate()方法的代码。可以看到,我们首先创建了一个Notification对象,然后调用了它的setLatestEventInfo()方法来为通知初始化布局和数据,并在这里设置了点击通知后就打开MainActivity。然后调用startForeground()方法就可以让MyService变成一个前台Service,并会将通知的图片显示出来。
    现在重新运行一下程序,并点击Start Service或Bind Service按钮,MyService就会以前台Service的模式启动了,并且在系统状态栏会弹出一个通栏图标,下拉状态栏后可以看到通知的详细内容,如下图所示。



    Service from local to remote


    参考资料

    相关文章

      网友评论

          本文标题:Service

          本文链接:https://www.haomeiwen.com/subject/zvcnjttx.html