zoukankan      html  css  js  c++  java
  • Android四大组件之Service浅见

    Service 是Android四大组件之一,可以在不显示界面的情况下在后台运行。还有一个作用是通过AIDL来实现进程间通信。

    Service的启动方式

    Service的启动方式有两种,startService()与bindService()

    startService():onCreate->onStartCommand(旧版本为onStart),结束通过stopService(),回调onDestroy

    如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStartCommand()方法

    bindService():onCreate->onBind,结束通过unBindService(),回调onUnbind->onDestroy.

    第一种方式启动Service,Service与调用者没有关联,调用者,比如Activity,finish掉后,Service还在运行。而bind就是两者绑定到一起,调用者结束了,Service也会结束。当然,调用者也可以通过unbindService()直接解绑。

    Service与Thread

    很多人搞不懂Service和Thread的区别,这里我谈谈我的理解。Service大家可以理解成没有界面的Activity,他运行在主线程(UI线程)中,而不是另起一个线程,所以说为什么不能在onStart(),onCreate()里进行耗时的操作,因为会阻塞主线程,甚至会引起ANR异常。通常在Service里进行耗时操作时都需要在Service中另起一个线程。同时,Service又分为local Service 和 remote Service ,分别为本地服务和远程服务。

    本地服务:在当前进程的主线程中,即与Client在同一进程,同时他是在运行UI线程上

    远程服务:另起一个进程,注意,是进程,不是线程。运行在该进程的主线程上。常用于进程间通信。

    可以通过添加android:process="remote"代码将Service设置成remote Service(默认是local)

    至于Thread就不用介绍了,所以大家可以看出来Service从某个层面上说,与Thread半毛钱关系没有。

    那么为什么要引进local Service呢,为什么不直接使用Thread呢?我的理解是local Service能够更加方便地对Thread进行管理和维护,比如如果你在当前Activity start一个子线程,当你离开这个Activity时,你将失去这个子线程的引用。而无论你Activity如何跳转,Service都可以安然地对子线程进行维护。

    Service通信

    Service 通过IBinder进行通信,首先创建内部类MyBinder继承实现IBinder接口的Binder类。重写onBind()方法返回MyBinder实例。

    public class MyService extends Service {
        private int count;
        private boolean quit;
        private MyBinder binder = new MyBinder();
        
        class MyBinder extends Binder{
            
            public int getCount(){
                return count;
            }
        }
        
        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            System.out.println("onbind");
            return binder;
        }
        
        
        
        @Override
        public void onCreate() {
            // TODO Auto-generated method stub
            super.onCreate();
            System.out.println("Create");
            new Thread(){
                @Override
                public void run() {
                    while(!quit){
                        try {
                            sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        count++;
                    }
                }
            }.start();
        }
        
        @Override
        public boolean onUnbind(Intent intent) {
            
            System.out.println("unbind");
            return true;
        }
        
        @Override
        public void onDestroy() {
            // TODO Auto-generated method stub
            super.onDestroy();
            this.quit = true;
            System.out.println("destroy");
        }
    
    }

     在调用Service的Activity中创建ServiceConnection实例,重写onServiceConnected,获取IBinder对象

    private ServiceConnection conn = new ServiceConnection() {
            //在Service连接失败时会调用该方法
            @Override
            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
                System.out.println("discouted");
            }
            //连接成功会调用该方法
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                // TODO Auto-generated method stub
                binder = (MyBinder) service;
            }
        };

    调用bindService(Intent service, ServiceConnection conn, int flags)时传入第二个参数就是ServiceConnection实例。获得IBinder对象后就可以调用里面的方法。

  • 相关阅读:
    asp.net mvc4 之Webapi之应用客户端访问服务器端
    c#设计模式-----单例模式
    ASP.NET MVC4中ViewBag、ViewData和TempData的使用和区别
    c# winform窗体间的传值
    Extjs-树 Ext.tree.TreePanel 动态加载数据
    Entity Framework(EF)(一)之database first
    MD5加密算法
    Extjs form 表单的 submit
    XML 解析错误:找不到根元素
    C语言断言
  • 原文地址:https://www.cnblogs.com/luction/p/3637924.html
Copyright © 2011-2022 走看看