Android Service使用误区

做应用的都应该熟悉Service这个类。Android四大组件之一。Activity的反面,没有界面,后台运行,但是它仍然是运行在主界面的。Activity退出时,Service仍可以继续执行。Service常见用于播放器,Service + Thread + Notification的模式很常见。Service也可以用来远程调用。

有一次遇到一位同事写的定位代码,他使用的service,利用service的特性,在需要定位的时候启动service进行定位。实际使用过程中,会出现这样的情况:定位工作不执行。刚开始没注意,一直以为是百度地图的问题。后来打印Log,发现Service被recycle了,因为内存吃紧,service被回收了。导致这部分工作出了问题。在这里提醒大家下,Service不一定会一直在后台执行,当内存不够时,会触发service回收,等到适当的时候,再根据service中onStartCommand( Intent intent, int flags, int startId);中的flag值进行重启动策略。

public class LocationService extends Service {

    private static final String TAG = LocationService.class.getSimpleName();
    private ServiceHandler mServiceHandler;
    private Looper mServiceLooper;

    public  LocationClient locationClient;

    private final int UPDATE_TIME = 3*1000;

    @Override
    public void onCreate() { 
        super.onCreate();

        L.log(AppInterface.LOG_DEBUG , 0 , TAG, "onCreate");

        HandlerThread thread = new HandlerThread(TAG,Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);

    }

    /**
     * 开始定位
     * @param context
     */
    public static void startLocation(Context context){
        Intent intent = new Intent(context,LocationService.class);
        intent.setAction("start_location");
        context.startService(intent);
    }

    /**
     * 停止定位
     * @param context
     */
    public static void stopLocation(Context context){
        Intent intent = new Intent(context,LocationService.class);
        intent.setAction("stop_location");
        context.startService(intent);
    }

    /**
     * @param context
     */
    public static void requestLocation(Context context){
        Intent intent = new Intent(context,LocationService.class);
        intent.setAction("request_location");
        context.startService(intent);
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }


    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            Intent intent = (Intent) msg.obj;
            if (intent != null) {
                String action = intent.getAction();
                if("start_location".equals(action)){ 
                    startLocation();
                }else if("stop_location".equals(action)){ 
                    stopLocation();
                }else if("request_location".equals(action)){ 
                    requestLocation();
                }
            }    
        }         
    }


    @Override
    public int onStartCommand(final Intent intent, int flags, int startId) {

        if(null != intent){
            Message msg = mServiceHandler.obtainMessage();
            msg.arg1 = startId;
            msg.obj = intent;
            mServiceHandler.sendMessage(msg);
            //被回收时,同时将intent传递进来,重启
            return Service.START_REDELIVER_INTENT;

        }
        return super.onStartCommand(intent, flags, startId);
    }


    private void initLocationConfig(){
        locationClient = new LocationClient(this);  
        LocationClientOption option = new LocationClientOption();  
        option.setOpenGps(true);    
        option.setAddrType("all");
        option.setPriority(LocationClientOption.GpsFirst); 
        option.setCoorType(BDLocation.BDLOCATION_GCJ02_TO_BD09LL);//百度地图的二次加密  
        //option.setCoorType(BDLocation.BDLOCATION_BD09LL_TO_GCJ02);
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//高精度定位
        option.setProdName(getString(R.string.app_name));                     
        option.setScanSpan(UPDATE_TIME); 
        option.setIsNeedAddress(false);
        option.disableCache(false);//不使用缓存定位
        locationClient.setLocOption(option);
        locationClient.registerLocationListener(new MyBDLocationListener());
    }

    private void startLocation(){

        if(locationClient==null){
            initLocationConfig();
        }
        if(!locationClient.isStarted()){
            locationClient.start();
        }
        locationClient.requestLocation();

        L.log(AppInterface.LOG_DEBUG, 0 , TAG , "the location client is start ----------");
    } 

    private void stopLocation(){ 
        if(locationClient!=null){
            if(locationClient.isStarted()){
                locationClient.stop();
                L.log(AppInterface.LOG_DEBUG, 0 , TAG , "the location client is stop ----------");
            }
        }
    }

    private void requestLocation(){

        if(locationClient!=null){
            if(!locationClient.isStarted()){
                locationClient.start();
            }
            locationClient.requestLocation();
            L.log(AppInterface.LOG_DEBUG, 0 , TAG ,"the location client is request ----------");
        }
    }

    private class MyBDLocationListener implements BDLocationListener{
        @Override  
        public void onReceiveLocation(BDLocation location) {  

            L.log(AppInterface.LOG_DEBUG, 0 , TAG ,"onReceiveLocation ----------");

            if (location == null) { 
                locationClient.start();   
                locationClient.requestLocation();
                return;  
            } 

            L.log(AppInterface.LOG_DEBUG, 0 , TAG , "type = " + location.getLocType() + "(gps type = " + BDLocation.TypeGpsLocation  + "), latitude = " + location.getLatitude() + " , longitude = " + location.getLongitude() + " , speed = " + location.getSpeed() + " , satelite = " + location.getSatelliteNumber()+",radius = " + location.getRadius());

            double latitude = location.getLatitude(); 
            double longitude = location.getLongitude();

            if((latitude >0 && latitude < 0.0000001) || (longitude >0 && longitude < 0.0000001)){
                //非法的经纬度
                return ;
            }

            String address = "";
            boolean isLocationValid = false;
            if(location.getLocType() == BDLocation.TypeNetWorkLocation){
                if(CheckUtil.isNetworkAvailable(LocationService.this)){
                    isLocationValid = true;
                    address = location.getAddrStr();
                }
            } else if(location.getLocType() == BDLocation.TypeGpsLocation){
                isLocationValid = true;
                address = location.getAddrStr();
            }
            //对位置进行传递,在LocationCallBack中进行回调
            LocationCallBack.getInstance(LocationService.this).setLocationData(location);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        stopLocation();

        L.log(AppInterface.LOG_DEBUG , 0 , TAG, "onDestroy");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值