美文网首页
android ServiceManager

android ServiceManager

作者: 京生京世 | 来源:发表于2017-05-14 00:17 被阅读146次

    之前使用Android绑定服务的功能,每次使用的时候都不是很方便,因为是异步的,代码也比较多,我现在想用同步的方式去调用服务的方法,一是代码少,二是调用方便。

    之前尝试先绑定服务,然后保留得到的服务接口对象,可是事与愿违,服务接口对象永不了多久就断开连接了。翻看了TelephonyManager代码,里面保存IBinder对象,于是就尝试保存服务的IBinder对象,需要调用服务的方法时通过IBinder对象去获取服务对象接口,测试之后没问题。

    ServiceManager

    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.content.pm.PackageManager;
    import android.content.pm.ResolveInfo;
    import android.os.IBinder;
    
    import java.util.Hashtable;
    import java.util.List;
    import java.util.Map;
    
    /**
     * 本地服务和远程服务的管理器。
     * 更加便捷的调用服务,以一种同步的方法去调用服务方法,
     * 调用之前需要先做好前提工作,之后就可以以同步的方式去调用服务方法
     * Created by 徐仕海 on 2017/5/13.
     */
    
    public class ServiceManager {
    
        private static ServiceManager instance;
    
        /**
         * 线程安全的到懒汉单例模式
         *
         * @return
         */
        public static ServiceManager getDefault() {
            ServiceManager tmp = instance;
            if (tmp == null) {
                synchronized (ServiceManager.class) {
                    instance = tmp = new ServiceManager();
                }
            }
            return tmp;
        }
    
        private Map<String, IBinder> cache = new Hashtable<>();//线程安全的Map
    
    
        /**
         * 添加动作为action的服务(IBinder)到cache中
         * 添加成功后便可以一直以同步的方法去调用服务方法。
         * 保存的IBinder对象不会像保存服务的接口对象会常常死掉。
         * 以后每次使用服务的方法时声称一次服务的接口就可以了,方便又安全。
         *
         * @param context
         * @param action
         */
        public void addService(final Context context, final String action) {
            if (isIBinderEnabled(action))
                return;
            Intent intent = getExplicitIntent(context, new Intent(action));
    if (intent == null)
                return;
            boolean ret = context.bindService(intent, new ServiceConnection() {
                @Override
                public void onServiceConnected(ComponentName name, IBinder service) {
                    cache.put(action, service);
                    context.unbindService(this);
                }
    
                @Override
                public void onServiceDisconnected(ComponentName name) {
                }
            }, Context.BIND_AUTO_CREATE);
        }
    
        /**
         * 获取显式的Intent,android5.0之后绑定服务只能是显式Intent不能用隐式Intent.
         *
         * @param context
         * @param implicitIntent
         * @return
         */
        private Intent getExplicitIntent(Context context, Intent implicitIntent) {
            // Retrieve all services that can match the given intent
            PackageManager pm = context.getPackageManager();
            List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
            // Make sure only one match was found
            if (resolveInfo == null || resolveInfo.size() != 1) {
                return null;
            }
            // Get component info and create ComponentName
            ResolveInfo serviceInfo = resolveInfo.get(0);
            String packageName = serviceInfo.serviceInfo.packageName;
            String className = serviceInfo.serviceInfo.name;
            ComponentName component = new ComponentName(packageName, className);
            // Create a new intent. Use the old one for extras and such reuse
            Intent explicitIntent = new Intent(implicitIntent);
            // Set the component to be explicit
            explicitIntent.setComponent(component);
            return explicitIntent;
        }
    
        /**
         * 获取action对应的服务的IBinder对象,这种对象可以用来生成可以直接使用的服务接口对象
         *
         * @param action
         * @return
         */
        public IBinder getService(String action) {
            return cache.get(action);
        }
    
        /**
         * 判断action对应的远程服务的IBinder是否可用
         *
         * @param action
         * @return
         */
        public boolean isIBinderEnabled(String action) {
            IBinder localBinder = getService(action);
            return localBinder != null && localBinder.isBinderAlive();
        }
    
    }
    
    

    DeviceManager

    import android.content.Context;
    
    import com.math.IMathAidlInterface;
    
    /**
     * Created by Administrator on 2017/5/13.
     */
    
    public class DeviceManager extends ServiceManager {
    
        private static DeviceManager instance;
    
        /**
         * 线程安全的到懒汉单例模式
         *
         * @return
         */
        public static DeviceManager getDefault() {
            DeviceManager tmp = instance;
            if (tmp == null) {
                synchronized (DeviceManager.class) {
                    instance = tmp = new DeviceManager();
                }
            }
            return tmp;
        }
    
    
    /**********************************************************************************************************************/
    
        final String ACTION_MATH = "com.math";
    
        public void addMathService(Context context) {
            addService(context, ACTION_MATH);
        }
    
        /**
         * 将action对应的远程服务转换成可用的IInterface
         *
         * @return
         */
        public IMathAidlInterface getIMath() {
            return IMathAidlInterface.Stub.asInterface(getService(ACTION_MATH));
        }
    }
    
    

    使用方法

    findViewById(R.id.tv_name).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    IMathAidlInterface iMathAidlInterface = DeviceManager.getDefault().getIMath();
                    try {
                        Toast.makeText(MainActivity.this, "" + iMathAidlInterface.add(1, 33), Toast.LENGTH_SHORT).show();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            });
    DeviceManager.getDefault().addMathService(this);
    

    相关文章

      网友评论

          本文标题:android ServiceManager

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