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 ...
随机推荐
- Ajax中post后台.net MVC中Controller的路径问题。
今天使用ajax的post方法,去访问mvc的controller,url的传值是 "//ProductCatalog/PostShareInfo",发现无论如何都访问不到. 我实 ...
- HTTP-HTTPS区别
超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂 ...
- 找"1"
题目:给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的次数. 要求:1.写一个函数f(N),返回1到N之间出现“1”的个数.例如f(12)=5. 2.在32位整数范围内 ...
- 软工1816 · Beta冲刺(7/7)
团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 协助完成安卓端的整合 完成安卓端的美化 协助制作宣传视频 接下来的计划 &am ...
- 寒假作业第二篇随笔(A+B)
Github链接:https://github.com/heihuifei/object-oriented A+B Format (20) Calculate a + b and output the ...
- 【Coursera】基于朴素贝叶斯的中文多分类器
一.算法说明 为了便于计算类条件概率\(P(x|c)\),朴素贝叶斯算法作了一个关键的假设:对已知类别,假设所有属性相互独立. 当使用训练完的特征向量对新样本进行测试时,由于概率是多个很小的相乘所得, ...
- CSS+JS笔记
CSS篇: 1.a标签去掉下划线 a { text-decoration:none; }
- Delphi 使用TAdoQuery执行存储过程的样例
procedure TCustomerForm.FindCustomerInfo;var strSql:string;begin // BL_HV_FindCustomerInfo 存储过程的名称 ...
- Windows安装ElastAlert问题总结
1.运行时出现UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xb4 in position 0: invalid start byte 或 ...
- 解决还原数据库是出现system.data.sqlclient.sqlerror filestream功能被禁用的问题
在master数据库下新建查询 输入如下语句: USE master GO RECONFIGURE 执行 成功还原数据库