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(); } } } }
服务的定义,使用和绑定(FileManagerService)
最新推荐文章于 2024-05-25 09:44:54 发布