服务的定义,使用和绑定(FileManagerService)

import android.app.Service;
import android.os.AsyncTask;

/**
 * Created by songyan on 2016/12/21.
 * 服务的基本用法
 *
 * ******定义一个服务
 * 继承Service类
 * 必须重写的方法是onBind
 * 要完成处理事情的逻辑需要重写的类有onCreate,onStartCommand,onDestroy
 *
 * 启动和停止服务
 * Intent startIntent=new Intent(this,FileManagerService.class);
 * startService(startIntent);
 * Intent stopIntent=new Intent(this,FileManagerService.class);
 * stopService(stopIntent);
 *
 * ******活动和服务进行通信
 * 在继承服务的类中需要书写的相关内容,写一个继承Binder的类,在必须重写的方法onBind中返回
 * 继承Binder的类的对象:
 * private ServiceBinder mBinder=new ServiceBinder();
 * public class FileManagerService extends Service {
 * private ServiceBinder extends Binder{
 *     定义相关方法
 * }
 * }
 * @Override
 * public IBinder onBind(Intent intent){
 *     return mBinder;
 * }
 *
 * *******在调用服务的类中需要完成的内容;
 * 定义一个继承Binder的类的对象,再初始化一个ServiceConnection接口,初始化该接口需要重写的类
 * 有onServiceDisconnected,onServiceConnected
 * 在以上方法中可以通过继承Binder的类的对象调用在服务中定义的相关方法,这样就将服务和活动联系
 * 在一起了,如下:
 * private FileManagerService.ServiceBinder serviceBinder;
 * private ServiceConnection connection=new ServiceConnection(){
 *     @Override
 *     public void onServiceDisconnected(ComponentName name{
 *     }
 *
 *     @Override
 *     public void onServiceConnected(ComponentName name,IBinder service){
 *         serviceBinder=(FileManagerService.ServiceBinder)service;
 *         //接下来就可以调用在服务中定义的相关方法了
 *     }
 * }
 *
 *最后进行服务和活动的绑定
 * Intent bindIntent=new Intent(this,ServiceBinder.class);
 * bindService(bindIntent,connection,BIND_AUTO_CREATE);
 * 解绑
 * unbindService(connection);
 */
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import FileOperationTask.CreateFolderTask;
import FileOperationTask.RenameTask;
import FileOperationTask.CutPasteFilesTask;
import FileOperationTask.CopyPasteFilesTask;

public class FileManagerService extends Service {
    public static final int FILE_FILTER_TYPE_UNKOWN=-1;
    public static final int FILE_FILTER_TYPE_DEFAULT=0;
    public static final int FILE_FILTER_TYPE_FOLDER=1;
    public static final int FILE_FILTER_TYPE_ALL=2;

    private static final String TAG="FileManagerService";
    private final HashMap<String,FileManagerActivityInfo> mActivityMap=
            new HashMap<String,FileManagerActivityInfo>();
    private ServiceBinder mBinder=null;//用于在onBind方法中返回

    private static class FileManagerActivityInfo{
        private BaseAsyncTask mTask=null;
        private FileInfoManager mFileInfoManager=null;
        private int mFilterType=FILE_FILTER_TYPE_DEFAULT;

        public void setTask(BaseAsyncTask task){
            this.mTask=task;
        }

        public void setFileInfoManager(FileInfoManager fileInfoManager){
            this.mFileInfoManager=fileInfoManager;
        }

        public void setFilterType(int filterType){
            this.mFilterType=filterType;
        }

        BaseAsyncTask getTask(){
            return mTask;
        }

        FileInfoManager getFileInfoManager(){
            return mFileInfoManager;
        }

        int getFilterType(){
            return mFilterType;
        }
    }

    //定义一个操作事件监听接口
    public interface OperationEventListener{
        int ERROR_CODE_NAME_VALID=100;
        int ERROR_CODE_SUCCESS=0;

        int ERROR_CODE_UNSUCCESS=-1;
        int ERROR_CODE_NAME_EMPTY=-2;
        int ERROR_CODE_NAME_TOO_LONG=-3;
        int ERROR_CODE_FILE_EXIST=-4;
        int ERROR_CODE_NOT_ENOUGH_SPACE=-5;
        int ERROR_CODE_DELETER_FAILS=-6;
        int ERROR_CODE_USER_CANCEL=-7;
        int ERROR_CODE_PASTE_TO_SUB=-8;
        int ERROR_CODE_UNKNOW=-9;
        int ERROR_CODE_COPY_NO_PERMISSION=-10;
        int ERROR_CODE_MKDIR_UNSUCCESS=-11;
        int ERROR_CODE_CUT_SAME_PATH=-12;
        int ERROR_CODE_BUSY=-100;
        int ERROR_CODE_DELETE_UNSUCCESS=-13;
        int ERROR_CODE_PASTE_UNSUCCESS=-14;
        int ERROR_CODE_DELETER_NO_PERMISSION=-15;
        int ERROR_CODE_COPY_GREATER_4G_TO_FAT32=-16;

        //这个方法将会被实现,在asynctask的onPreExecute中被调用
        void onTaskPrepare();

        //这个方法将会被实现,在asynctask的onProgressUpdate方法中被调用
        //prgressIfo是ProgressInfo的信息,将会在UI中被更新
        void onTaskProgress(ProgressInfo progressInfo);

        //这个方法将会被实现,在asynctask的onPostExecute中被调用
        //参数result是asynctask的doInBackground()的结果
        void onTaskResult(int result);
    }

    @Override
    public void onCreate(){
        super.onCreate();
        mBinder=new ServiceBinder();
        AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);//设置AsyncTask的运行方式?
    }

    @Override
    public int onStartCommand(Intent intent,int flags,int startId){
        LogUtils.d(TAG,"onStartCommand...");
        super.onStartCommand(intent,flags,startId);
        return START_NOT_STICKY;
        //“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务
    }

    public class ServiceBinder extends Binder{
        //这个方法得到FileServiceInstance的实例
        public FileManagerService getServiceInstance(){
            return FileManagerService.this;
        }
    }

    //这个方法初始化特定活动的FileInfoManager
    public FileInfoManager initFileInfoManager(String activityName){
        FileManagerActivityInfo activityInfo=mActivityMap.get(activityName);
        if(activityInfo==null){
            activityInfo=new FileManagerActivityInfo();
            activityInfo.setFileInfoManager(new FileInfoManager());
            mActivityMap.put(activityName,activityInfo);
        }
        return activityInfo.getFileInfoManager();
    }

    @Override
    public IBinder onBind(Intent intent){
        DrmManager.getInstance().init(this);
        return mBinder;
    }

    //这个方法检查服务忙不忙,这表示对于一些特定活动task id存不存在
    public boolean isBusy(String activityName){
        boolean ret=false;
        FileManagerActivityInfo activityInfo=mActivityMap.get(activityName);
        if(activityInfo==null){
            return ret;
        }
        BaseAsyncTask task=activityInfo.getTask();
        if(task!=null){
            return task.isTaskBusy();
        }
        return false;
    }

    private FileManagerActivityInfo getActivityInfo(String activityName){
        FileManagerActivityInfo activityInfo=mActivityMap.get(activityName);
        if(activityInfo==null){
            throw new IllegalArgumentException("this activity not init in Service");
        }
        return activityInfo;
    }

    //这个方法设置列表过滤器,决定什么类型的items会被列出在ListView中
    public void setListType(int type,String activityName){
        getActivityInfo(activityName).setFilterType(type);
    }

    //这个方法通过启动一个新的CreateFolderTask来完成创建文件夹的工作
    public void createFolder(String activityName,String destFolder,OperationEventListener listener){
        if(isBusy(activityName)){
            listener.onTaskResult(OperationEventListener.ERROR_CODE_BUSY);
        }else{
            FileInfoManager fileInfoManager=getActivityInfo(activityName).getFileInfoManager();
            int filterType=getActivityInfo(activityName).getFilterType();
            if(fileInfoManager!=null){
                BaseAsyncTask task=new CreateFolderTask(fileInfoManager,listener,this,destFolder,filterType);
                getActivityInfo(activityName).setTask(task);
                task.execute();
            }
        }
    }

    public void rename(String activityName,FileInfo srcFile,FileInfo dstFile,OperationEventListener listener){
        LogUtils.d(TAG,"rename Start,activityName="+activityName);

        if(isBusy(activityName)){
            listener.onTaskResult(OperationEventListener.ERROR_CODE_BUSY);
        }else {
            FileInfoManager fileInfoManager=getActivityInfo(activityName).getFileInfoManager();
            int filterType=getActivityInfo(activityName).getFilterType();
            if(fileInfoManager!=null){
                BaseAsyncTask task=new RenameTask(fileInfoManager,listener,this,srcFile,dstFile,filterType);
                getActivityInfo(activityName).setTask(task);
                task.execute();
            }
        }
    }

    private int filterPasteList(List<FileInfo> fileInfoList, String destFolder){
        int remove=0;
        Iterator<FileInfo> iterator=fileInfoList.iterator();
        while(iterator.hasNext()){
            FileInfo fileInfo=iterator.next();
            if(fileInfo.isDirectory()){
                if((destFolder+MountPointManager.SEPARATOR).startsWith(fileInfo.getFileAbsolutePath()+
                MountPointManager.SEPARATOR)){
                    iterator.remove();
                    remove++;
                }
            }
        }
        return remove;
    }

    public void deleteFiles(String activityName,List<FileInfo>fileInfoList,
                            OperationEventListener listener){
        LogUtils.d(TAG,"deleteFiles Start,activityName="+activityName);
        if(isBusy(activityName)){
            listener.onTaskResult(OperationEventListener.ERROR_CODE_BUSY);
        }else {
            FileInfoManager fileInfoManager=getActivityInfo(activityName).getFileInfoManager();
            if(fileInfoManager!=null){
                BaseAsyncTask task=new FileOperationTask.DeleteFilesTask(fileInfoManager,
                        listener,this,fileInfoList);
                getActivityInfo(activityName).setTask(task);
                task.execute();
            }
        }
    }

    public void cancel(String activityName){
        LogUtils.d(TAG,"cancel service,activityName="+activityName);
        BaseAsyncTask task=getActivityInfo(activityName).getTask();
        if(task!=null){
            task.cancel(true);//终止task(线程)
        }
    }

    public void pasteFiles(String activityName,List<FileInfo> fileInfoList,String dstFolder,
                           int type,OperationEventListener listener){
        LogUtils.d(TAG,"pasteFiles Start,activityName="+activityName);
        if(isBusy(activityName)){
            listener.onTaskResult(OperationEventListener.ERROR_CODE_BUSY);
            return;
        }
        if(filterPasteList(fileInfoList,dstFolder)>0){//要粘贴的文件中存在于目标文件夹
            listener.onTaskResult(OperationEventListener.ERROR_CODE_PASTE_TO_SUB);
        }
        FileInfoManager fileInfoManager=getActivityInfo(activityName).getFileInfoManager();
        if(fileInfoManager==null){
            LogUtils.w(TAG,"mFileInfoManager.get FileInfoManager=null");
            listener.onTaskResult(OperationEventListener.ERROR_CODE_UNKNOW);
            return;
        }
        BaseAsyncTask task=null;
        if(fileInfoList.size()>0){
            switch (type){
                case FileInfoManager.PASTE_MODE_CUT:
                    if(isCutSamePath(fileInfoList,dstFolder)){
                        listener.onTaskResult(OperationEventListener.ERROR_CODE_CUT_SAME_PATH);
                        return;
                    }
                    task=new CutPasteFilesTask(fileInfoManager,listener,getApplicationContext(),
                            fileInfoList,dstFolder);
                    getActivityInfo(activityName).setTask(task);
                    task.execute();
                    break;
                case FileInfoManager.PASTE_MODE_COPY:
                    task=new CopyPasteFilesTask(fileInfoManager,listener,getApplicationContext(),
                            fileInfoList,dstFolder);
                    getActivityInfo(activityName).setTask(task);
                    task.execute();
                    break;
                default:
                    listener.onTaskResult(OperationEventListener.ERROR_CODE_UNKNOW);
                    return;
            }
        }
    }

    private boolean isCutSamePath(List<FileInfo>fileInfoList,String dstFolder){
        for(FileInfo fileInfo:fileInfoList){
            if(fileInfo.getFileParentPath().equals(dstFolder)){//要拷贝文件的父路径和目的路径相同
                return true;
            }
        }
        return false;
    }

    public void listFiles(String activityName,String path,OperationEventListener listener){
        LogUtils.d(TAG,"listFiles,activityName="+activityName+",path="+path);
        if(isBusy(activityName)){
            LogUtils.d(TAG,"listFiles,cancel other background task...");
            BaseAsyncTask task=getActivityInfo(activityName).getTask();
            if(task!=null){
                task.removeListener();
                task.cancel(true);
            }
        }
        LogUtils.d(TAG,"listFiles,do list.");
        FileInfoManager fileInfoManager=getActivityInfo(activityName).getFileInfoManager();
        int filterType=getActivityInfo(activityName).getFilterType();
        if(fileInfoManager!=null){
            LogUtils.d(TAG,"listFiles filterType="+filterType);
            BaseAsyncTask task=new ListFileTask(getApplicationContext(),fileInfoManager,listener,
                    path,filterType);
            getActivityInfo(activityName).setTask(task);
            task.execute();
        }
    }

    public void getDetailInfo(String activityName,FileInfo file,OperationEventListener listener){
        LogUtils.d(TAG,"getDetailInfo,activityName="+activityName);
        if(isBusy(activityName)){
            listener.onTaskResult(OperationEventListener.ERROR_CODE_BUSY);
        }else {
            FileInfoManager fileInfoManager=getActivityInfo(activityName).getFileInfoManager();
            if(fileInfoManager!=null){
                BaseAsyncTask task=new DetailInfoTask(fileInfoManager,listener,file);
                getActivityInfo(activityName).setTask(task);
                task.execute();
            }
        }
    }

    //当服务连接断开的时候这个方法将listener从task上移除
    public void disconnected(String activityName){
        LogUtils.d(TAG,"disconnected,activityName="+activityName);
        BaseAsyncTask task=getActivityInfo(activityName).getTask();
        if(task!=null){
            task.removeListener();
        }
    }

    //当对话被销毁货值重建的时候这个方法通过设置新的监听给task来重新连接正在运行的task
    public void reconnected(String activityName,OperationEventListener listener){
        LogUtils.d(TAG,"reconnected,activityName="+activityName);
        BaseAsyncTask task=getActivityInfo(activityName).getTask();
        if(task!=null){
            task.setListener(listener);
        }
    }

    public boolean isDetailTask(String activityName){
        FileManagerActivityInfo aInfo=mActivityMap.get(activityName);
        if(null==aInfo){
            LogUtils.d(TAG,"activity is not attach:"+activityName);
            return false;
        }
        BaseAsyncTask task=aInfo.getTask();
        if(task!=null && task instanceof DetailInfoTask){
            return true;
        }
        return false;
    }

    public boolean isHeavyOperationTask(String activityName){
        FileManagerActivityInfo aInfo=mActivityMap.get(activityName);
        if(null==aInfo){
            LogUtils.d(TAG,"activity is not attach:"+activityName);
            return false;
        }
        BaseAsyncTask task=aInfo.getTask();
        if(task!=null &&(task instanceof CutPasteFilesTask || task instanceof CopyPasteFilesTask
        || task instanceof DetailInfoTask)){
            return true;
        }
        return false;
    }

    public void search(String activityName,String searchName,String path,
                       OperationEventListener operationEvent){
        LogUtils.d(TAG,"search,activityName="+activityName+",searchName="+searchName+",path"+path);
        if(isBusy(activityName)){
            cancel(activityName);
        }else{
            FileInfoManager fileInfoManager=getActivityInfo(activityName).getFileInfoManager();
            if(fileInfoManager!=null){
                BaseAsyncTask task=new SearchTask(fileInfoManager,operationEvent,searchName,path,getContentResolver());
                getActivityInfo(activityName).setTask(task);
                task.execute();
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值