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
activity 与 service 之间的通信的更多相关文章
- activity与service之间的通信方式
Activity之间的通信 1.activity与activity的通信可以通过Intent来封装数据,startActivityForResult()来实现,当跳转的activity调用finish ...
- Activity与Service之间交互并播放歌曲的实现代码
Activity与Service之间交互并播放歌曲,为了方便,我把要播放的歌曲定死了,大家可以灵活改进 MService: 复制代码代码如下: package com.tiantian.test;im ...
- Service 之间如何通信?- 每天5分钟玩转 Docker 容器技术(101)
微服务架构的应用由若干 service 组成.比如有运行 httpd 的 web 前端,有提供缓存的 memcached,有存放数据的 mysql,每一层都是 swarm 的一个 service,每个 ...
- activity与service进程内通信
package com.example.binbin.testbinder; import android.app.Service; import android.content.Intent; im ...
- 101、Service 之间如何通信?(Swarm08)
参考https://www.cnblogs.com/CloudMan6/p/7967419.html 微服务架构的应用由若干 service 构成.比如有运行 httpd 的 web 前端,有提供 ...
- Aactivity和Service之间的通信
一.在activity中定义三个按钮 一个开启服务 一个关闭服务,还有一个是向服务发送广播 当创建出Serevice时先执行Service的onCreate()创建服务后只执行一次 以后每次点击开启 ...
- Android 数据传递(二)Activity与fragment之间的通信
在网上找到了一篇总结的非常好的文章,我这里就贴出他的博文地址.自己就不再写这个方面的总结了. Activity与Fragment通信(99%)完美解决方案
- Activity 与 Service 之间的消息传递
BgService代码 public class BgService extends Service { public static final String TAG = "BgServic ...
- 通过messenger实现activity与service的相互通信
布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:to ...
随机推荐
- 基于openvswitch+Docker构建SDN网络测试环境 (使用ovs-docker进行构建)
这是一篇之前写的笔记,主要记录了使用openvswitch + Docker 等进行一个小型的SDN网络搭建的操作步骤.由于 之前临时有其他任务,耽搁了一下,最近开始重新整理,并计划开发一个简单的Py ...
- Ruby知识点一:方法
1.实例方法 接收者是对象本身的方法 2.类方法 接收者是类本身的方法,调用类方法时,可以使用::或者.两个符号. 类名.方法名 类名::方法名 3.函数式方法 没有接收者(接收者省略而已)的方法 4 ...
- Bing词典vs有道词典比对测试报告——体验篇之成长性及用户控制权
成长性: 会记住曾经查询过的单词或例句与有道词典实现基本一样,并无特别亮点. 用户有控制权: 必应词典和有道词典都能实现基本的查询前进和后退.以及无法查找结果,能顺利进行反馈. 我们在输入完单词按下回 ...
- Daily Scrum3 11.5
昨天的任务已经完成,但是大家分析后发现进度稍有些慢.今天各自都在调整进度,不再拖延别人的工作. 今日任务: 杨伊:做问卷调查,准备用户体验篇内容. 徐钧鸿:把Xueba中Utility 向闸瓦移植 张 ...
- Scrum Meeting 10.30
成员 今日任务 明日计划 用时 徐越 配置servlet环境,设计开发文档 设计开发文档,配置服务器,使得本地可以访问服务器 5h 武鑫 软件界面设计:学习使用Activity和Fragment 设计 ...
- 20135316王剑桥 linux第六周课实验笔记
6.存储器层次结构 6.1存储技术 1.如果你的程序需要的数据是存储在CPU寄存器中的,那么在执行期间,在零个周期内就能访问到它们.如果存储在高速缓冲中,需要1-10个周期.如果存储在主存中,需要50 ...
- 20172329 2018-2019《Java程序设计与数据结构》课程总结
作者:lalalouye(20172329王文彬) 2018-2019年大二Java程序设计与数据结构课程总目录:第一周 第二周 第三周 第四周 第五周 第六周 第七周 第八周 第九周 实验一 实验二 ...
- web10 动态action的应用
电影网站:www.aikan66.com 项目网站:www.aikan66.com游戏网站:www.aikan66.com图片网站:www.aikan66.com书籍网站:www.aikan66.co ...
- ListView高效分页
使用控件自带的分页功能时,会先将所查询的数据全部加载出来,若数据量较大,则造成浏览器端等待时间过长. 然而在庞大的数据量,用户所需要的不过是那么几条,甚至只要其中的一条数据,所以,为了减少开销,每次只 ...
- 为什么要读这本书《java编程思想》
在学校学习编程语言只是浅显的了解,不理解的的东西有很多 ,想通过这本书对java语言有更深的理解,对于以后的学习和工作会有很大的好处.与其了了草草的看你一些书,知其然而不知其所以然,这不是我想要的学习 ...