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

  • 相关阅读:
    《DSP using MATLAB》 示例 Example 9.12
    《DSP using MATLAB》示例 Example 9.11
    《DSP using MATLAB》示例 Example 9.10
    《DSP using MATLAB》示例Example 9.9
    《DSP using MATLAB》示例 Example 9.8
    《DSP using MATLAB》示例Example 9.7
    《DSP using MATLAB》示例 Example 9.6
    《DSP using MATLAB》示例Example 9.5
    《DSP using MATLAB》示例 Example 9.4
    (转载)【C++11新特性】 nullptr关键字
  • 原文地址:https://www.cnblogs.com/androidsuperman/p/6389953.html
Copyright © 2011-2022 走看看