activity和service通信:通过binder

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

首先是下载更新apk的service:

  1. public class UpdateVersionService extends Service {
  2.  
  3. private final String tag = "young";
  4. private Context context = this;
  5. private BaseApplication application;
  6. private DownloadBinder binder;
  7. private String apkUrl;// apk下载地址
  8. private String saveFileName;// 下载安装包路径
  9. private Thread downLoadThread;// 下载apk线程
  10. private int progress;// 进度条
  11. private final int NOTIFY_ID = 0;
  12. private NotificationManager notificationManager;
  13. private Notification notification;// 消息通知
  14. private Builder builder = null;
  15. private boolean canceled;
  16. private boolean serviceIsDestory = false;
  17. private int lastRate = 0;
  18.  
  19. private Handler handler = new Handler() {
  20. public void handleMessage(android.os.Message msg) {
  21. switch (msg.what) {
  22. case 0:
  23. // Log.v(tag, "success---");下载完成并安装
  24. application.setDownload(false);
  25. notificationManager.cancel(NOTIFY_ID);
  26. installApk();
  27. break;
  28. case 1:
  29. int rate = msg.arg1;
  30. // Log.v(tag, "rate---");刷新进度
  31. application.setDownload(true);
  32. if (rate < 100) {
  33. RemoteViews remoteView = notification.contentView;
  34. remoteView.setTextViewText(R.id.tv_progress, rate + "%");
  35. remoteView.setProgressBar(R.id.progressbar, 100, rate,
  36. false);
  37. } else {
  38. // Log.v(tag, "下载完成");
  39. notification.flags = Notification.FLAG_AUTO_CANCEL;
  40. Intent intent = new Intent(context, MainActivity.class);
  41. PendingIntent contentIntent = PendingIntent.getActivity(
  42. context, 0, intent,
  43. PendingIntent.FLAG_UPDATE_CURRENT);
  44. builder.setContentTitle(getResources().getString(
  45. R.string.download_finish_title));
  46. builder.setContentText(getResources().getString(
  47. R.string.download_finish_text));
  48. notification.contentIntent = contentIntent;
  49. serviceIsDestory = true;
  50. stopSelf();
  51. }
  52. notificationManager.notify(NOTIFY_ID, notification);
  53. break;
  54. case 2:
  55. // Log.v(tag, "cancel---");取消下载
  56. application.setDownload(false);
  57. notificationManager.cancel(NOTIFY_ID);
  58. break;
  59. case 3:
  60. // Log.v(tag, "error---");出现异常
  61. application.setDownload(true);
  62. notificationManager.cancel(NOTIFY_ID);
  63. Toast.makeText(context,
  64. getResources().getString(R.string.download_alter),
  65. Toast.LENGTH_SHORT).show();
  66. stopSelf();
  67. break;
  68. }
  69.  
  70. };
  71. };
  72.  
  73. /**
  74. * 安装APK
  75. */
  76. private void installApk() {
  77. File apkfile = new File(saveFileName);
  78. if (!apkfile.exists()) {
  79. ToastUtil.toasts(context,
  80. getResources().getString(R.string.download_alter));
  81. return;
  82. }
  83. Intent intent = new Intent(Intent.ACTION_VIEW);
  84. intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  85. intent.setDataAndType(Uri.parse("file://" + apkfile.toString()),
  86. "application/vnd.android.package-archive");
  87. startActivity(intent);
  88. }
  89.  
  90. @Override
  91. public void onCreate() {
  92. // TODO Auto-generated method stub
  93. super.onCreate();
  94. // Log.v(tag, "onCreate");
  95. application = (BaseApplication) getApplication();
  96. this.binder = new DownloadBinder();
  97. notificationManager = (NotificationManager) this
  98. .getSystemService(android.content.Context.NOTIFICATION_SERVICE);
  99. }
  100.  
  101. @Override
  102. public int onStartCommand(Intent intent, int flags, int startId) {
  103. // TODO Auto-generated method stub
  104. // Log.v(tag, "onStartCommand");
  105. apkUrl = intent.getStringExtra("apkUrl");
  106. if (!StringUtil.isEmpty(apkUrl)) {
  107. saveFileName = FileUtils.getAppPath(context, apkUrl).getPath();
  108. }
  109. return super.onStartCommand(intent, flags, startId);
  110.  
  111. }
  112.  
  113. @Override
  114. public void onDestroy() {
  115. // TODO Auto-generated method stub
  116. super.onDestroy();
  117. //Log.v(tag, "onDestroy");
  118. application.setDownload(false);
  119. }
  120.  
  121. @Override
  122. public IBinder onBind(Intent intent) {
  123. // Log.v(tag, "onBind");
  124. return binder;
  125. }
  126.  
  127. @Override
  128. public boolean onUnbind(Intent intent) {
  129. // Log.v(tag, "onUnbind");
  130. return super.onUnbind(intent);
  131. }
  132.  
  133. @Override
  134. public void onRebind(Intent intent) {
  135. // Log.v(tag, "onRebind");
  136. super.onRebind(intent);
  137. }
  138.  
  139. /**
  140. * 下载binder
  141. *
  142. * @author Administrator
  143. *
  144. */
  145. public class DownloadBinder extends Binder {
  146.  
  147. public void start() {
  148. if (downLoadThread == null || !downLoadThread.isAlive()) {
  149. setNotification();
  150. canceled = false;
  151. startDownloadApk();
  152. }
  153. }
  154. public void cancel() {
  155. canceled = true;
  156. }
  157.  
  158. public int getProgress() {
  159. return progress;
  160. }
  161.  
  162. public boolean getCanceled() {
  163. return canceled;
  164. }
  165.  
  166. public boolean isDestoryService() {
  167. return serviceIsDestory;
  168. }
  169.  
  170. public void cancleNotification() {
  171. handler.sendEmptyMessage(2);
  172. }
  173. }
  174.  
  175. /**
  176. * 下载apk
  177. */
  178. private void startDownloadApk() {
  179. downLoadThread = new Thread(downApkRunnable);
  180. downLoadThread.start();
  181. }
  182.  
  183. private Runnable downApkRunnable = new Runnable() {
  184.  
  185. @Override
  186. public void run() {
  187. try {
  188. URL url = new URL(apkUrl);
  189. // Log.v(tag, "apkUrl---" + apkUrl);
  190. HttpURLConnection connection = (HttpURLConnection) url
  191. .openConnection();
  192. connection.connect();
  193. int length = connection.getContentLength();
  194. InputStream inputStream = connection.getInputStream();
  195. String apkUrls = saveFileName;
  196. // Log.v(tag, "apkUrls---" + apkUrls);
  197. File apkFile = new File(apkUrls);
  198. if(apkFile.exists()){
  199. Log.v(tag, "true---" + apkFile.getAbsolutePath());
  200. }
  201. FileOutputStream outputStream = new FileOutputStream(apkFile);
  202. int count = 0;
  203. byte[] buffer = new byte[1024];
  204. do {
  205. int readNum = inputStream.read(buffer);
  206. count += readNum;
  207. progress = (int) (((float) count / length) * 100);
  208. Message msg = new Message();
  209. msg.what = 1;
  210. msg.arg1 = progress;
  211. if (progress > lastRate + 1) {
  212. handler.sendMessage(msg);
  213. lastRate = progress;
  214. }
  215. if (readNum <= 0) {
  216. handler.sendEmptyMessage(0);
  217. canceled = true;
  218. break;
  219. }
  220. outputStream.write(buffer, 0, readNum);
  221. } while (!canceled);
  222. if (outputStream != null) {
  223. outputStream.close();
  224. }
  225. if (inputStream != null) {
  226. inputStream.close();
  227. }
  228. } catch (Exception e) {
  229. Log.d("young","Exception...."+ e.toString()) ;
  230. handler.sendEmptyMessage(3);
  231. }
  232.  
  233. }
  234. };
  235.  
  236. /**
  237. * 设置下载通知栏
  238. */
  239. private void setNotification() {
  240. // String tickerText = getResources().getString(R.string.download_start);
  241. String tickerText = "开始下载";
  242. long when = System.currentTimeMillis();
  243. builder = new Builder(this);
  244. builder.setSmallIcon(R.drawable.ic_launcher);
  245. builder.setWhen(when);
  246. builder.setTicker(tickerText);
  247. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
  248. notification = builder.build();
  249. }
  250. notification.flags = Notification.FLAG_ONGOING_EVENT;
  251. RemoteViews contentView = new RemoteViews(getPackageName(),
  252. R.layout.download_notification_layout);
  253. contentView.setTextViewText(R.id.tv_name,
  254. getResources().getString(R.string.download_title));
  255. notification.contentView = contentView;
  256. Intent intent = new Intent(this, MainActivity.class);
  257. PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
  258. intent, PendingIntent.FLAG_UPDATE_CURRENT);
  259. notification.contentIntent = contentIntent;
  260. notificationManager.notify(NOTIFY_ID, notification);
  261. }
  262.  
  263. }

调用如上service:

声明binder对象:

  1. private UpdateVersionService.DownloadBinder binder;

通过intent绑定service:

  1. Intent intent =new Intent(mContext, UpdateVersionService.class);
  2. intent.putExtra("apkUrl",apk_url);
  3. mContext.startService(intent);
  4. mContext.bindService(intent,conn, Context.BIND_AUTO_CREATE);
  1. ServiceConnection conn = new ServiceConnection() {
  2.  
  3. @Override
  4. public void onServiceDisconnected(ComponentName name) {
  5. // TODO Auto-generated method stub
  6. }
  7.  
  8. @Override
  9. public void onServiceConnected(ComponentName name, IBinder service) {
  10. // TODO Auto-generated method stub
  11. binder = (UpdateVersionService.DownloadBinder) service;
  12. // 开始下载
  13. binder.start();
  14. }
  15. };

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

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

注意在mainfest文件中注册service:

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

service与activity通信:通过广播

  1. public class TestService extends Service {
  2. /**
  3. * 进度条的最大值
  4. */
  5. public static final int MAX_PROGRESS = 100;
  6. /**
  7. * 进度条的进度值
  8. */
  9. private int progress = 0;
  10.  
  11. private Intent intent = new Intent("com.soyoungboy.communication.RECEIVER");
  12.  
  13. /**
  14. * 模拟下载任务,每秒钟更新一次
  15. */
  16. public void startDownLoad(){
  17. new Thread(new Runnable() {
  18.  
  19. @Override
  20. public void run() {
  21. while(progress < MAX_PROGRESS){
  22. progress += 1;
  23. //发送Action为com.example.communication.RECEIVER的广播
  24. intent.putExtra("progress", progress);
  25. sendBroadcast(intent);
  26.  
  27. }
  28. }
  29. }).start();
  30. }
  31.  
  32. @Override
  33. public int onStartCommand(Intent intent, int flags, int startId) {
  34. startDownLoad();
  35. return super.onStartCommand(intent, flags, startId);
  36. }
  37.  
  38. @Override
  39. public IBinder onBind(Intent intent) {
  40. return null;
  41. }
  42.  
  43. }
  1. /**
  2. * 广播接收器
  3. * @author len
  4. *
  5. */
  6. public class MsgReceiver extends BroadcastReceiver {
  7.  
  8. @Override
  9. public void onReceive(Context context, Intent intent) {
  10. //拿到进度,更新UI
  11. int progress = intent.getIntExtra("progress", 0);
  12. Toast.makeText(context,"progress = "+progress,Toast.LENGTH_LONG).show();
  13. }
  14.  
  15. }

mainfest文件:

  1. <receiver android:name=".service.MsgReceiver">
  2. <intent-filter>
  3. <action android:name="com.soyoungboy.communication.RECEIVER"></action>
  4. </intent-filter>
  5. </receiver>
  6. <service android:name=".service.TestService">
  7. <intent-filter>
  8. <action android:name="com.soyoungboy.communication.MSG_ACTION"/>
  9. </intent-filter>
  10. </service>

当然也可以使用EventBus或者RxJava

activity 与 service 之间的通信的更多相关文章

  1. activity与service之间的通信方式

    Activity之间的通信 1.activity与activity的通信可以通过Intent来封装数据,startActivityForResult()来实现,当跳转的activity调用finish ...

  2. Activity与Service之间交互并播放歌曲的实现代码

    Activity与Service之间交互并播放歌曲,为了方便,我把要播放的歌曲定死了,大家可以灵活改进 MService: 复制代码代码如下: package com.tiantian.test;im ...

  3. Service 之间如何通信?- 每天5分钟玩转 Docker 容器技术(101)

    微服务架构的应用由若干 service 组成.比如有运行 httpd 的 web 前端,有提供缓存的 memcached,有存放数据的 mysql,每一层都是 swarm 的一个 service,每个 ...

  4. activity与service进程内通信

    package com.example.binbin.testbinder; import android.app.Service; import android.content.Intent; im ...

  5. 101、Service 之间如何通信?(Swarm08)

    参考https://www.cnblogs.com/CloudMan6/p/7967419.html   微服务架构的应用由若干 service 构成.比如有运行 httpd 的 web 前端,有提供 ...

  6. Aactivity和Service之间的通信

    一.在activity中定义三个按钮 一个开启服务  一个关闭服务,还有一个是向服务发送广播 当创建出Serevice时先执行Service的onCreate()创建服务后只执行一次 以后每次点击开启 ...

  7. Android 数据传递(二)Activity与fragment之间的通信

    在网上找到了一篇总结的非常好的文章,我这里就贴出他的博文地址.自己就不再写这个方面的总结了. Activity与Fragment通信(99%)完美解决方案

  8. Activity 与 Service 之间的消息传递

    BgService代码 public class BgService extends Service { public static final String TAG = "BgServic ...

  9. 通过messenger实现activity与service的相互通信

    布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:to ...

随机推荐

  1. easyx图形库做贪吃蛇游戏

    编程总是对着一个黑窗口,可以说是非常乏味了,于是喵喵就翻出来了以前用easyx图形库做图形界面的贪吃蛇游戏. 不过大家只是当做提高编程的乐趣来学习吧,想进一步做的话可以学习QT,还有其他的框架. 这是 ...

  2. Netty源码分析第3章(客户端接入流程)---->第3节: NioSocketChannel的创建

    Netty源码分析第三章: 客户端接入流程 第三节: NioSocketChannel的创建 回到上一小节的read()方法: public void read() { //必须是NioEventLo ...

  3. Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第7节: 获取异线程释放的对象

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第七节: 获取异线程释放的对象 上一小节分析了异线程回收对象, 原理是通过与stack关联的WeakOrder ...

  4. eclipse创建spring boot项目加载不到application.properties配置文件

    在配置文件application.properties中修改了端口号,但重启服务后发现端口号并没有跟着改变,发现是项目启动时没有加载application.properties文件导致 解决:项目-& ...

  5. XSS工具

    1.BEEF KALI中启动BEEFXSS PAYLOAD为 <script src=”http://攻击机IP:3000/hook.js”></script> 将攻击代码插入 ...

  6. 2-Fifth Scrum Meeting20151205

    任务安排 闫昊: 今日完成:设计本地数据库. 明日任务:请假.(最近代码写得多……很累……) 唐彬: 今日完成:ios客户端代码的了解. 明日任务:ios客户端代码的深度学习. 史烨轩: 今日完成: ...

  7. 实验一linux 系统简介和实验二基本概念及操作

    作业 zy e

  8. Oracle 11g R2 for Win7旗舰版(64位)- 安装

    1.下载Oracle 11g R2 for Windows的版本                                   下载地址:http://www.oracle.com/techne ...

  9. 【CSAPP笔记】4. 汇编语言——基础知识

    程序的机器级表示 计算机能读懂是机器代码(machine code)-- 用字节序列编码的低级操作 -- 也就是0和1.编译器基于编程语言的规则.目标机器的指令集和操作系统的规则,经过一系列阶段产生机 ...

  10. Alpha阶段敏捷冲刺④

    1.提供当天站立式会议照片一张. 每个人的工作 (有work item 的ID),并将其记录在码云项目管理中: 昨天已完成的工作. 改善界面设计 今天计划完成的工作. 数据库和程序的连接 后端框架的继 ...