美文网首页
StartService & BindService结合Down

StartService & BindService结合Down

作者: 杰子他爸 | 来源:发表于2019-05-15 11:55 被阅读0次

    1、startService和BindService都是作为后台服务,但区别在于生命周期,多次启动,Activity销毁是否解绑。

    2、关于startService简介声明:

    public  IBinder   onBind(Intent intent){

    Log.e("call","onBind");   returnnull;    }

    //开启服务Intent service =new Intent(this, MyService.class);  startService(service);

    //结束服务stopService(service);

    调用多次startService,onCreate只有第一次会被执行,而onStartCommand会执行多次。

    3、关于BindService简介声明:

    //开启服务   Intent service =newIntent(this, MyService.class); 

    MyConnection conn =new  MyConnection();

    //第一个参数:Intent意图

    //第二个参数:是一个接口,通过这个接口接收服务开启或者停止的消息,并且这个参数不能为null

    //第三个参数:开启服务时的操作,BIND_AUTO_CREATE代表自动创建

    servicebindService(service, conn, BIND_AUTO_CREATE);

    同时自己实现conn:

    //结束服务unbindService(conn);

    onBind返回值不为null的情况分析:

    以下内容转自网友:

    4、startService和bindService开启服务时,他们与activity之间的关系

    1)startService开启服务以后,与activity就没有关联,不受影响,独立运行。

    2)bindService开启服务以后,与activity存在关联,退出activity时必须调用unbindService方法,否则会报ServiceConnection泄漏的错误。

    以上知识点结合DownloadManager实践:

    public class DownloadServiceextends Service {

    public static final StringBUNDLE_KEY_DOWNLOAD_URL ="download_url";

        public static final int UNBIND_SERVICE =0x002;

        private DownloadBinderbinder;

        public static final int HANDLE_DOWNLOAD =0x001;

        //下载任务ID

        private long downloadId;

        private StringdownloadUrl;

        private DownloadManagerdownloadManager;

        private OnProgressListeneronProgressListener;

        private BroadcastReceiverdownLoadBroadcast;

        private ScheduledExecutorServicescheduledExecutorService;

        @Override

        public void onCreate() {

    super.onCreate();

            binder =new DownloadBinder();

            scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();

            scheduledExecutorService.scheduleAtFixedRate(progressRunnable, 0, 1, TimeUnit.SECONDS);

        }

    @Override

        public IBinderonBind(Intent intent) {

    downloadUrl = intent.getStringExtra(BUNDLE_KEY_DOWNLOAD_URL);

            downloadApk(downloadUrl, "lotteryInstall.apk");

            return binder;

        }

    /**

    * 下载最新APK

    */

        private void downloadApk(String url, String name) {

    downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

            DownloadManager.Request request =new DownloadManager.Request(Uri.parse(url));

            /**设置用于下载时的网络状态*/

            request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);

            /**设置通知栏是否可见*/

            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);

            /**设置漫游状态下是否可以下载*/

            request.setAllowedOverRoaming(false);

            /**如果我们希望下载的文件可以被系统的Downloads应用扫描到并管理,

    我们需要调用Request对象的setVisibleInDownloadsUi方法,传递参数true.*/

            request.setVisibleInDownloadsUi(true);

            //设置可以被系统扫描到

            request.allowScanningByMediaScanner();

            /**设置文件保存路径*/

            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, name);

            /**将下载请求放入队列, return下载任务的ID*/

            downloadId =downloadManager.enqueue(request);

            registerBroadcast();

        }

    /**

    * 注册广播

    */

        private void registerBroadcast() {

    /**注册service 广播 1.任务完成时 */

            IntentFilter intentFilter =new IntentFilter();

            intentFilter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);

            registerReceiver(downLoadBroadcast =new DownLoadBroadcast(), intentFilter);

        }

    /**

    * 注销广播

    */

        private void unregisterBroadcast() {

    if (downLoadBroadcast !=null) {

    unregisterReceiver(downLoadBroadcast);

                downLoadBroadcast =null;

            }

    }

    public class DownloadBinderextends Binder {

    /**

    * 返回当前服务的实例

    *

            * @return

            */

            public DownloadServicegetService() {

    return DownloadService.this;

            }

    }

    /**

    * 接受下载完成广播

    */

        private class DownLoadBroadcastextends BroadcastReceiver {

    @Override

            public void onReceive(Context context, Intent intent) {

    checkStatus();

            }

    }

    //检查下载状态

        private void checkStatus() {

    DownloadManager.Query query =new DownloadManager.Query();

            //通过下载的id查找

            query.setFilterById(downloadId);

            Cursor c =downloadManager.query(query);

            if (c.moveToFirst()) {

    int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));

                switch (status) {

    //下载暂停

                    case DownloadManager.STATUS_PAUSED:

    break;

                    //下载延迟

                    case DownloadManager.STATUS_PENDING:

    break;

                    //正在下载

                    case DownloadManager.STATUS_RUNNING:

    LogWriter.writeExceptionLog("DownloadUtils  正在下载");

                        //下载完成

                    case DownloadManager.STATUS_SUCCESSFUL:

    LogWriter.writeExceptionLog("DownloadUtils  app下载完成");

                        close();

                        if (onProgressListener !=null) {

    onProgressListener.onProgress(UNBIND_SERVICE);

                        }

    DeviceAPIFactory.getRobotSystemServer().startApkUpdate(new IMessageBagReceiver() {

    @Override

                            public void onMessageBagReceived(MessageBag resMsgBag) {

    AppUpgradeService.startActionUpdateApp(App.getInstance(),

                                        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() +"/lotteryInstall.apk", BuildConfig.APPLICATION_ID);

                            }

    @Override

                            public void onMessageBagTimeout(MessageBag reqMsgBag) {

    ToastUtil.showMessage("发送数据超时,App升级失败,请重试!");

                            }

    });

    break;

                    //下载失败

                    case DownloadManager.STATUS_FAILED:

    LogWriter.writeExceptionLog("DownloadUtils  下载失败");

    break;

                }

    }

    c.close();

        }

    /**

    * 关闭定时器,线程等操作

    */

        private void close() {

    if (scheduledExecutorService !=null && !scheduledExecutorService.isShutdown()) {

    scheduledExecutorService.shutdown();

            }

    if (downLoadHandler !=null) {

    downLoadHandler.removeCallbacksAndMessages(null);

            }

    }

    public HandlerdownLoadHandler =new Handler() {

    @Override

            public void handleMessage(Message msg) {

    super.handleMessage(msg);

                switch (msg.what) {

    case HANDLE_DOWNLOAD:

    if (onProgressListener !=null &&HANDLE_DOWNLOAD == msg.what) {

    onProgressListener.onProgress(getDownloadPercent(downloadId));

                        }

    break;

                    default:

    break;

                }

    }

    };

        private RunnableprogressRunnable =new Runnable() {

    @Override

            public void run() {

    updateProgress();

            }

    };

        /**

    * 发送Handler消息更新进度和状态

    */

        private void updateProgress() {

    downLoadHandler.sendEmptyMessage(HANDLE_DOWNLOAD);

        }

    public interface OnProgressListener {

    /**

    * 下载进度

    *

            * @param fraction 已下载/总大小

    */

            void onProgress(int fraction);

        }

    /**

    * 对外开发的方法

    *

        * @param onProgressListener

        */

        public void setOnProgressListener(OnProgressListener onProgressListener) {

    this.onProgressListener = onProgressListener;

        }

    /**

    * 获取下载进度

    *

        * @param downloadId

        * @return

        */

        private int getDownloadPercent(long downloadId) {

    DownloadManager.Query query =new DownloadManager.Query().setFilterById(downloadId);

            Cursor c =downloadManager.query(query);

            if (c.moveToFirst()) {

    int downloadBytesIdx = c.getColumnIndexOrThrow(

    DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);

                int totalBytesIdx = c.getColumnIndexOrThrow(

    DownloadManager.COLUMN_TOTAL_SIZE_BYTES);

                long totalBytes = c.getLong(totalBytesIdx);

                long downloadBytes = c.getLong(downloadBytesIdx);

                return (int) (downloadBytes *100 / totalBytes);

            }

    return 0;

        }

    @Override

        public void onDestroy() {

    super.onDestroy();

            unregisterBroadcast();

        }

    }

    Activity部分代码掠影:

    private ServiceConnectionconn =new ServiceConnection() {

    @Override

        public void onServiceConnected(ComponentName name, IBinder service) {

    DownloadService.DownloadBinder binder = (DownloadService.DownloadBinder) service;

            DownloadService downloadService = binder.getService();

            //接口回调,下载进度

            downloadService.setOnProgressListener(new DownloadService.OnProgressListener() {

    @Override

                public void onProgress(float fraction) {

    LogUtil.i(TAG, "下载进度:" + fraction);

                    bnp.setProgress((int)(fraction *100));

                    //判断是否真的下载完成进行安装了,以及是否注册绑定过服务

                    if (fraction == DownloadService.UNBIND_SERVICE &&isBindService) {

    unbindService(conn);

                        isBindService =false;

                        MToast.shortToast("下载完成!");

                    }

    }

    });

        }

    @Override

        public void onServiceDisconnected(ComponentName name) {

    }

    };

    That's all !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    相关文章

      网友评论

          本文标题:StartService & BindService结合Down

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