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

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. gitlab+jenkins持续集成(二)

    1.jenkins服务器上的配置 -bin.tar.gz -C /opt/ yum install -y git /conf/settings.xml #只需更改maven的地址 <?xml v ...

  2. 如何在window服务器上搭建一个能代替ftp的传输工具

    通常对于服务器上的文件管理和数据传输都是利用ftp来实现,但随着存储技术的发展,数据资产的存储规模和复杂程度不断提高,传统的ftp传输显得有笨重.今天给大家介绍一款能够取代ftp的在线文档管理软件—— ...

  3. Hyperledger Fabric chaincode 开发(疑难解答)

    Q&A Q1: 使用fabric release 1.2 进行golang chaincode开发时报错: ..\..\hyperledger\fabric\vendor\github.com ...

  4. day22 模块-collections,time,random,pickle,shelve等

    一.引入模块的方式: 1. 认识模块 模块可以认为是一个py文件. 模块实际上是我们的py文件运行后的名称空间 导入模块: 1. 判断sys.modules中是否已经导入过该模块 2. 开辟一个内存 ...

  5. mkswap命令详解

    基础命令学习目录首页 原文链接:http://blog.51cto.com/arlen99/1743841 mkswap命令用于在一个文件或者设备上建立交换分区.在建立完之后要使用sawpon命令开始 ...

  6. react-native ListView 性能问题

    常见性能问题已经有很多答案,这里要说的是使用ListView时注意的地方,    ListView的容器需要设定一个固定高度, 不然ListView中的item过多,会把整体页面撑开,设置的 remo ...

  7. Redis学习(一):CentOS下redis安装和部署

    1.基础知识  redis是用C语言开发的一个开源的高性能键值对(key-value)数据库.它通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止redis支持的键值数据类型如下字符串.列表 ...

  8. Fourteenth scrum meeting

    闫昊 今日完成:整理上一阶段代码,规划第二阶段实施过程 明日完成:学习讨论区开发 唐彬 今日完成:整理上一阶段代码,规划第二阶段实施过程 明日完成:学习学习进度部分开发 史烨轩 今日完成:整理上一阶段 ...

  9. 迎来OO的曙光,总结规格的意义——OO第四次博客总结

    一切都要结束了,砥砺前行~ 一.测试与正确性论证的效果差异 测试,顾名思义就是我们暴力用大量数据轰炸编写的程序的过程.日常的OO过程中,我们经常互相寻求“测试集”,正是因为测试使用特定数据对我们的功能 ...

  10. 简单复利计算java板

    一.要求: 1.客户说:帮我开发一个复利计算软件. 2如果按照单利计算,本息又是多少呢? 3.假如30年之后要筹措到300万元的养老金,平均的年回报率是3%,那么,现在必须投入的本金是多少呢? 4.利 ...