美文网首页
Android Service

Android Service

作者: cfyushi | 来源:发表于2017-05-08 20:35 被阅读0次

    简介

    Android系统的后台服务组件,适用于无界面、长时间运行的场景

    特点

    后台运行,没有用户界面,不可交互;
    比非活动的Activity优先级高,被系统回收可能性小;
    被回收后可以自动恢复;
    进程间通讯

    生命周期

    void onCreate()

    Service第一次创建时调用,只会被调用一次

    int onStartCommand(Intent intent, int flags, int startId)

    每次客户端调用startService时调用,可以被调用多次,startId表示被调用的次数,0开始

    START_STICKY:kill后,重启,intent值为null
    START_NOT_STICKY:kill后,不重启
    START_REDELIVER_INTENT: kill后,重启,intent值保留
    START_STICKY_COMPATIBILITY: START_STICKY的兼容版本,不一定保证能重启

    IBinder onBind(Intent intent)

    客户端绑定时调用,返回Ibinder对象用于通讯

    boolean onUnbind(Intent intent)

    解绑

    void onDestroy()

    Service销毁时调用

    示例
    public class MyService extends Service {
        private final String TAG = MyService.class.getSimpleName();
        private MyBinder mMyBinder = new MyBinder();
        public MyService() {
        }
    
        @Override
        public void onCreate() {
            Log.d(TAG, "onCreate");      
            super.onCreate();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.d(TAG, "onStartCommand intent:" + intent + " startId:" + startId);
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            return super.onUnbind(intent);
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            Log.d(TAG, "onBind");
            return mMyBinder;
        }
    
        @Override
        public void onDestroy() {
            Log.d(TAG, "onDestroy");
            super.onDestroy();
        }
    
        public class MyBinder extends Binder {
            public void test(String test){
                Log.d(TAG,"test - :" + test.length());
            }
        }
    }
    

    Mainfest配置

    android:name: service名称,必须
    android:process:进程名,默认在创建进程,可选
    android:enabled:能否被系统实例化,必须
    android:exported:能否被其他应用调用,必须
    android:permission:权限,可选
    intent-filter:意图过滤,可选

            <service
                android:name=".MyService"
                android:enabled="true"
                android:exported="true"
                android:permission="cfyushi.wzs.123">
                <intent-filter>
                    <action android:name="com.cfyushi.MyService" />
                </intent-filter>
            </service>
    

    启动和停止

    startService(Intent service)

    启动服务,可多次调用

    stopService(Intent name)

    停止服务

    Intent的创建

    Intent intent = new Intent(); intent.setClassName(this,“类名");
    
    Intent intent = new Intent();intent.setAction(“intent-filter”);intent.setPackage(“应用包名");
    
    Intent intent  = new Intent(context, xx.class)
    

    绑定和解绑

    boolean bindService(Intent service, ServiceConnection conn, int flags)

    客户端调用此接口进行绑定,然后通讯交互

    BIND_AUTO_CREATE:当收到绑定请求时,如果服务尚未创建,则即刻创建

    BIND_DEBUG_UNBIND:调试解绑接口,仅Debug

    BIND_NOT_FOREGROUND系统将阻止驻留该服务的进程具有前台优先级,仅在后台运行

    ServiceConnection

    private ServiceConnection mSC = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.d(TAG, "onServiceConnected name:" + name);
                mBinder = (MyService.MyBinder)service;       
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.d(TAG, "onServiceDisconnected");
                mMyService = null;
            }
        };
    

    void unbindService(ServiceConnection conn)

    解绑

    IntentService

    Service是在UI线程运行,不能处理耗时任务
    IntentService会单独创建线程顺序执行Intent请求、执行完毕会自动停止、只需要执行onHandleIntent,其他方法(onBind、onStartCommand)默认实现

    public class MyIntentService extends IntentService {
       
    
        private final String TAG =MyIntentService.class.getSimpleName();
    
        public MyIntentService() {
            super("MyIntentService");
        }
        
        @Override
        public void onCreate() {
            super.onCreate();
        }
    
    
        @Override
        public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
        }
    
        @Override
        protected void onHandleIntent(Intent intent) {
            if (intent != null) {
                //获取action和参数
                final String action = intent.getAction();
                Log.d(TAG, "onHandleIntent action:" + action);
                Log.d(TAG, "Thread:" + Thread.currentThread());
                final String param1 = intent.getStringExtra("EXTRA_PARAM1");
                final String param2 = intent.getStringExtra("EXTRA_PARAM2");
            }
        }
        
    }
    

    Aidl

    支持基本类型、String、List、Map和序列化对象

    创建aidl文件

    以IMyAidlInterface.aidl为例

    interface IMyAidlInterface {
        int test(String test);
    }
    

    配置Mainfest

         <service
                android:name=".MyAidlService"
                android:enabled="true"
                android:exported="true"
                android:process=":aidl">
                <intent-filter>
                    <action android:name="com.cfyushi.MyAidlService" />
                </intent-filter>
            </service>
    

    创建Aidl service

    public class MyAidlService extends Service {
    
        private final String TAG = MyAidlService.class.getSimpleName();
    
        public MyAidlService() {
        }
    
    
        @Override
        public void onCreate() {
            Log.d(TAG, "onCreate");
            super.onCreate();
        }
    
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.d(TAG, "onStartCommand intent:" + intent + " startId:" + startId);
           return super.onStartCommand(intent, flags, startId);    
        }
    
        
        @Override
        public void onDestroy() {
            Log.d(TAG, "onDestroy");
            super.onDestroy();
        }
    
    
        @Override
        public boolean onUnbind(Intent intent) {
            return super.onUnbind(intent);
        }
    
    
        @Override
        public IBinder onBind(Intent intent) {
            return mStub;
        }
    
        IMyAidlInterface.Stub mStub = new IMyAidlInterface.Stub() {
    
            /**
             *
             * @param test
             * @return
             * @throws RemoteException
             */
            @Override
            public int test(String test) throws RemoteException {
                String s = null;
                Log.d(TAG, "test:" + test);
                Log.d(TAG, "s:" + s.length());
                return 0;
            }
        };
    }
    

    Binder

    Binder是android系统中常用的IPC通讯机制,以内核层Binder驱动为主,Client和Server以此基础进行通讯。

    Paste_Image.png

    Service保活

    程序异常报错、系统回收等原因会导致Service停止工作,因此保活至关重要,以下措施在系统强杀和root流氓软件强杀下无效,也没必要有效,我们不做流氓。

    设置为前台进程

    Notification.Builder nb = new Notification.Builder(getApplication());
            Intent notificationIntent = new Intent(this, MainActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
            nb.setWhen(System.currentTimeMillis());
            nb.setTicker("1111");
            nb.setContentTitle("sevrice 在前台");
            nb.setContentIntent(pendingIntent);
            startForeground(1, nb.build());
    

    onStartCommand返回START_STICK

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

    native层保活

    在native层创建守护线程,github地址

    还有一些不推荐使用的方法,配置android:persistent=“true”、重写Service的onDestroy方法、服务互绑和监听闹钟及广播

    相关文章

      网友评论

          本文标题:Android Service

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