Android内存优化-方式一:使用保守的Service

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yaoming168/article/details/88946369

1、 简介
IntentService是Service的子类,根据需要处理异步请求(以intent表示)。客户端通过调用startService(Intent) 发送请求,该Service根据需要启动,使用工作线程处理依次每个Intent,并在停止工作时停止自身。
这种“工作队列处理器”模式通常用于从应用程序的主线程中卸载任务。 IntentService类的存在是为了简化这种模式。 要使用它,扩展IntentService并实现onHandleIntent(Intent)。 IntentService将收到Intents,启动一个工作线程,并根据需要停止该服务。
所有请求都在单个工作线程处理 - 它们可能需要很长的时间(并且不会阻止应用程序的主循环),但是一次只会处理一个请求。

2 、代码
在IntentService中处理下载请求(模拟),并将进度更新到Ui。
MyIntentService.java代码如下:

public class MyIntentService extends IntentService {
    private final static String TAG = "MyIntentService";
    public static final String ACTION_DOWN_IMG = "down.image";
    public static final String ACTION_DOWN_VID = "down.vid";
    public static final String ACTION_DOWN_PROGRESS = "com.zpengyong.down.progress";
    public static final String ACTION_SERVICE_STATE = "com.zpengyong.service.state";    
    public static final String PROGRESS = "progress";
    public static final String SERVICE_STATE = "service_state";
    //构造方法 一定要实现此方法否则Service运行出错。
    public MyIntentService() {
        super("MyIntentService");
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate");
        sendServiceState("onCreate");
    }
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.i(TAG, "");
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i(TAG, "onHandleIntent thread:"+Thread.currentThread());
        String action = intent.getAction();
        if(action.equals(ACTION_DOWN_IMG)){
            for(int i = 0; i < 100; i++){
                try{ //模拟耗时操作
                    Thread.sleep(50);
                }catch (Exception e) {
                }
                sendProgress(i);
            }
        }else if(action.equals(ACTION_DOWN_VID)){
            for(int i = 0; i < 100; i++){
                try{ //模拟耗时操作
                    Thread.sleep(70);
                }catch (Exception e) {
                }
                sendProgress(i);
            }
        }
        Log.i(TAG, "onHandleIntent end");
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy");
        sendServiceState("onDestroy");
    }
    //发送Service的状态
    private void sendServiceState(String state){
        Intent intent = new Intent();
        intent.setAction(ACTION_SERVICE_STATE);
        intent.putExtra(SERVICE_STATE, state);
        sendBroadcast(intent);
    }
    //发送进度
    private void sendProgress(int progress){
        Intent intent = new Intent();
        intent.setAction(ACTION_DOWN_PROGRESS);
        intent.putExtra(PROGRESS, progress);
        sendBroadcast(intent);
    }
}

使用IntentService的方法:
1.继承IntentService。
2.实现不带参数的构造方法,并且调用父类IntentService的构造方法。
3.实现onHandleIntent方法。

3 IntentService源码解析
路径:frameworks/base/core/java/android/app/IntentService.java
先看下IntentService的构造方法和onCreate()。

public abstract class IntentService extends Service {
    //Creates an IntentService.  Invoked by your subclass's constructor.
    public IntentService(String name) {
        super();
            mName = name;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }
    ...
}

IntentService 是继承Service的一个抽象类,所以需要继承IntentService 并必须实现其抽象方法onHandleIntent。
继承IntentService需要实现一个空的构造器,并且调用IntentService的构造器。
在onCreate()方法中创建了一个HandlerThread,并允许该线程。
获取子线程中的Looper实例,然后创建与子线程绑定的Handler对象。
接着看IntentService的onStart()。

public void onStart(Intent intent, int startId) {
    Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
}

在onStart方法中,创建Message对象,并将“消息”通过mServiceHandler发送到子线程中的消息队列中。
我们知道这些消息处理还是会分发到Handler中。接着看mServiceHandler

private final class ServiceHandler extends Handler {
    public ServiceHandler(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
}

消息会在handlerMessage中处理,该方法中调用了onHandleIntent,所以我们需要实现onHandleIntent,在该方法中做我们要做的任务。而消息处理完成后,调用stopSelf将自身Service销毁。这里可能会有疑问,既然一个任务执行完成后就会执行stopSelf,那多个任务是怎么处理的呢?这里stopSelf(msg.arg1),会先看队列中是否有消息待处理,如果有则继续处理后面的消息,没有才会将Service销毁。
接着看IntentService的onDestroy方法

@Override
public void onDestroy() {
    mServiceLooper.quit();
}

在IntentService的onDestroy方法中会调用looper的quit方法,将子线程的消息循环停止,等待任务完成后结束子线程。
4 总结
IntentService是一个比较便捷的类,省了我们在创建Thread,但是并不能适合所有的情况,它会创建一个线程,多个任务按顺序执行,并且执行过程中不能够取消该任务。所以还是需要根据情况进行使用。

猜你喜欢

转载自blog.csdn.net/yaoming168/article/details/88946369
今日推荐