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 ...
随机推荐
- 【坚持】Selenium+Python学习记录 DAY10
2018/05/31-2018/06/1 [官方文档](https://www.jetbrains.com/help/pycharm/set-up-a-git-repository.html) 通过p ...
- SDWebImage 错误汇总
1. [UIImageView sd_setImageWithURL:placeholderImage:]: unrecognized selector sent to instance 打包静态库 ...
- rev命令详解
基础命令学习目录首页 rev命令将文件中的每行内容以字符为单位反序输出,即第一个字符最后输出,最后一个字符最先输出,依次类推. #cat a.txt wo shi mcw, nihao how do ...
- TeamWork#2,Week 2,We are sixsix!
We are sixsix! (从左至右依次是:郝倩.张志浩.高雅智[高哥].牛强.张明培育.彭林江.王卓) 郝倩,来自120617班,我们组7个成员中唯一一个6行政班以外的成员.为了达成组队条件,彭 ...
- 作业1-MathExam
MathExam 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 10 30 • Estim ...
- 团队项目-NABCD
用户需求分析与NABCD 模拟经营类(SIM)游戏:玩家模拟经营一家软件公司,平台初步定为Android. Need需求 任何一款游戏都要有自己的定位和目标群体,这些 iiMediaResearch数 ...
- Linux基础入门--06
简单的文本处理 实验介绍 这一节我们将介绍这几个命令:tr.col.join.paste 1.tr: -d:删除和set1匹配的字符,不是全词匹配也不是按字符顺序匹配 -s:除去指定的连续并重复的字符 ...
- 20162328蔡文琛 大二 十二周课上测试 hash
- 编写了几个Java类,但是一直运行某一个class,这种是因为:main方法写错
编写了几个Java类,但是一直运行某一个class,这种是因为:main方法写错
- PAT 1001 A+B Fotmat
源码 1001. A+B Format (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Calcula ...