zoukankan      html  css  js  c++  java
  • activity 与 service 之间的通信

    activity和service通信:通过binder

    举个我实际项目中的例子:在service中下载更新应用

    首先是下载更新apk的service:

    public class UpdateVersionService extends Service {
    
        private final String tag = "young";
        private Context context = this;
        private BaseApplication application;
        private DownloadBinder binder;
        private String apkUrl;// apk下载地址
        private String saveFileName;// 下载安装包路径
        private Thread downLoadThread;// 下载apk线程
        private int progress;// 进度条
        private final int NOTIFY_ID = 0;
        private NotificationManager notificationManager;
        private Notification notification;// 消息通知
        private Builder builder = null;
        private boolean canceled;
        private boolean serviceIsDestory = false;
        private int lastRate = 0;
    
        private Handler handler = new Handler() {
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                    case 0:
                        //  Log.v(tag, "success---");下载完成并安装
                        application.setDownload(false);
                        notificationManager.cancel(NOTIFY_ID);
                        installApk();
                        break;
                    case 1:
                        int rate = msg.arg1;
                        //   Log.v(tag, "rate---");刷新进度
                        application.setDownload(true);
                        if (rate < 100) {
                            RemoteViews remoteView = notification.contentView;
                            remoteView.setTextViewText(R.id.tv_progress, rate + "%");
                            remoteView.setProgressBar(R.id.progressbar, 100, rate,
                                    false);
                        } else {
                            //    Log.v(tag, "下载完成");
                            notification.flags = Notification.FLAG_AUTO_CANCEL;
                            Intent intent = new Intent(context, MainActivity.class);
                            PendingIntent contentIntent = PendingIntent.getActivity(
                                    context, 0, intent,
                                    PendingIntent.FLAG_UPDATE_CURRENT);
                            builder.setContentTitle(getResources().getString(
                                    R.string.download_finish_title));
                            builder.setContentText(getResources().getString(
                                    R.string.download_finish_text));
                            notification.contentIntent = contentIntent;
                            serviceIsDestory = true;
                            stopSelf();
                        }
                        notificationManager.notify(NOTIFY_ID, notification);
                        break;
                    case 2:
                        // Log.v(tag, "cancel---");取消下载
                        application.setDownload(false);
                        notificationManager.cancel(NOTIFY_ID);
                        break;
                    case 3:
                        // Log.v(tag, "error---");出现异常
                        application.setDownload(true);
                        notificationManager.cancel(NOTIFY_ID);
                        Toast.makeText(context,
                                getResources().getString(R.string.download_alter),
                                Toast.LENGTH_SHORT).show();
                        stopSelf();
                        break;
                }
    
            };
        };
    
        /**
         * 安装APK
         */
        private void installApk() {
            File apkfile = new File(saveFileName);
            if (!apkfile.exists()) {
                ToastUtil.toasts(context,
                        getResources().getString(R.string.download_alter));
                return;
            }
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.parse("file://" + apkfile.toString()),
                    "application/vnd.android.package-archive");
            startActivity(intent);
        }
    
        @Override
        public void onCreate() {
            // TODO Auto-generated method stub
            super.onCreate();
            //  Log.v(tag, "onCreate");
            application = (BaseApplication) getApplication();
            this.binder = new DownloadBinder();
            notificationManager = (NotificationManager) this
                    .getSystemService(android.content.Context.NOTIFICATION_SERVICE);
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // TODO Auto-generated method stub
            //  Log.v(tag, "onStartCommand");
            apkUrl = intent.getStringExtra("apkUrl");
            if (!StringUtil.isEmpty(apkUrl)) {
                saveFileName =  FileUtils.getAppPath(context, apkUrl).getPath();
            }
            return super.onStartCommand(intent, flags, startId);
    
        }
    
        @Override
        public void onDestroy() {
            // TODO Auto-generated method stub
            super.onDestroy();
            //Log.v(tag, "onDestroy");
            application.setDownload(false);
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // Log.v(tag, "onBind");
            return binder;
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            //  Log.v(tag, "onUnbind");
            return super.onUnbind(intent);
        }
    
        @Override
        public void onRebind(Intent intent) {
            //  Log.v(tag, "onRebind");
            super.onRebind(intent);
        }
    
        /**
         * 下载binder
         *
         * @author Administrator
         *
         */
        public class DownloadBinder extends Binder {
    
            public void start() {
                if (downLoadThread == null || !downLoadThread.isAlive()) {
                    setNotification();
                    canceled = false;
                    startDownloadApk();
                }
            }
    
            public void cancel() {
                canceled = true;
            }
    
            public int getProgress() {
                return progress;
            }
    
            public boolean getCanceled() {
                return canceled;
            }
    
            public boolean isDestoryService() {
                return serviceIsDestory;
            }
    
            public void cancleNotification() {
                handler.sendEmptyMessage(2);
            }
        }
    
        /**
         * 下载apk
         */
        private void startDownloadApk() {
            downLoadThread = new Thread(downApkRunnable);
            downLoadThread.start();
        }
    
        private Runnable downApkRunnable = new Runnable() {
    
            @Override
            public void run() {
                try {
                    URL url = new URL(apkUrl);
                   // Log.v(tag, "apkUrl---" + apkUrl);
                    HttpURLConnection connection = (HttpURLConnection) url
                            .openConnection();
                    connection.connect();
                    int length = connection.getContentLength();
                    InputStream inputStream = connection.getInputStream();
                    String apkUrls = saveFileName;
                   // Log.v(tag, "apkUrls---" + apkUrls);
                    File apkFile = new File(apkUrls);
                    if(apkFile.exists()){
                        Log.v(tag, "true---" + apkFile.getAbsolutePath());
                    }
                    FileOutputStream outputStream = new FileOutputStream(apkFile);
                    int count = 0;
                    byte[] buffer = new byte[1024];
                    do {
                        int readNum = inputStream.read(buffer);
                        count += readNum;
                        progress = (int) (((float) count / length) * 100);
                        Message msg = new Message();
                        msg.what = 1;
                        msg.arg1 = progress;
                        if (progress > lastRate + 1) {
                            handler.sendMessage(msg);
                            lastRate = progress;
                        }
                        if (readNum <= 0) {
                            handler.sendEmptyMessage(0);
                            canceled = true;
                            break;
                        }
                        outputStream.write(buffer, 0, readNum);
                    } while (!canceled);
                    if (outputStream != null) {
                        outputStream.close();
                    }
                    if (inputStream != null) {
                        inputStream.close();
                    }
                } catch (Exception e) {
                    Log.d("young","Exception...."+ e.toString())  ;
                    handler.sendEmptyMessage(3);
                }
    
            }
        };
    
        /**
         * 设置下载通知栏
         */
        private void setNotification() {
            // String tickerText = getResources().getString(R.string.download_start);
            String tickerText = "开始下载";
            long when = System.currentTimeMillis();
            builder = new Builder(this);
            builder.setSmallIcon(R.drawable.ic_launcher);
            builder.setWhen(when);
            builder.setTicker(tickerText);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                notification = builder.build();
            }
            notification.flags = Notification.FLAG_ONGOING_EVENT;
            RemoteViews contentView = new RemoteViews(getPackageName(),
                    R.layout.download_notification_layout);
            contentView.setTextViewText(R.id.tv_name,
                    getResources().getString(R.string.download_title));
            notification.contentView = contentView;
            Intent intent = new Intent(this, MainActivity.class);
            PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                    intent, PendingIntent.FLAG_UPDATE_CURRENT);
            notification.contentIntent = contentIntent;
            notificationManager.notify(NOTIFY_ID, notification);
        }
    
    }

    调用如上service:

    声明binder对象:

    private UpdateVersionService.DownloadBinder binder;

    通过intent绑定service:

     Intent intent =new Intent(mContext, UpdateVersionService.class);
                intent.putExtra("apkUrl",apk_url);
                mContext.startService(intent);
                mContext.bindService(intent,conn, Context.BIND_AUTO_CREATE);
    ServiceConnection conn = new ServiceConnection() {
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
            }
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                // TODO Auto-generated method stub
                binder = (UpdateVersionService.DownloadBinder) service;
                // 开始下载
                binder.start();
            }
        };

    如上在onserviceConnected中调用binder.start(),也就是调用DownloadBinder的start()方法;

    start方法里面调用startDownloadApk()开启下载应用的线程,在线程里面通过hander控制Notifition上面进度显示,下载完成调用安装apk程式。

    注意在mainfest文件中注册service:

    <service android:name="com.chexiu.service.UpdateVersionService" >
            </service>

    service与activity通信:通过广播

    public class TestService extends Service {
        /**
         * 进度条的最大值
         */
        public static final int MAX_PROGRESS = 100;
        /**
         * 进度条的进度值
         */
        private int progress = 0;
    
        private Intent intent = new Intent("com.soyoungboy.communication.RECEIVER");
    
    
        /**
         * 模拟下载任务,每秒钟更新一次
         */
        public void startDownLoad(){
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while(progress < MAX_PROGRESS){
                        progress += 1;
                        //发送Action为com.example.communication.RECEIVER的广播
                        intent.putExtra("progress", progress);
                        sendBroadcast(intent);
    
                    }
                }
            }).start();
        }
    
    
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startDownLoad();
            return super.onStartCommand(intent, flags, startId);
        }
    
    
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
    
    }
    /**
     * 广播接收器
     * @author len
     *
     */
    public class MsgReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            //拿到进度,更新UI
            int progress = intent.getIntExtra("progress", 0);
            Toast.makeText(context,"progress = "+progress,Toast.LENGTH_LONG).show();
        }
    
    }

    mainfest文件:

    <receiver android:name=".service.MsgReceiver">
                <intent-filter>
                    <action android:name="com.soyoungboy.communication.RECEIVER"></action>
                </intent-filter>
            </receiver>
            <service android:name=".service.TestService">
                <intent-filter>
                    <action android:name="com.soyoungboy.communication.MSG_ACTION"/>
                </intent-filter>
            </service>

     当然也可以使用EventBus或者RxJava

  • 相关阅读:
    ABP
    妖道角
    检测空值,以及会不会出现mapping类型不一致的问题
    wcf服务契约代理链
    wcf服务契约继承
    win64+anaconda+xgboost(转)
    python中迭代问题
    ROC曲线和AUC值(转)
    python中split()和split(' ')的区别
    str和repr的区别(转)
  • 原文地址:https://www.cnblogs.com/androidsuperman/p/6389953.html
Copyright © 2011-2022 走看看