这篇文章主要介绍了Android实现Activity、Service与Broadcaster三大组件之间互相调用的方法,结合实例形式详细分析了Activity、Service与Broadcaster三大组件相互调用的原理,实现方法与相关注意事项,需要的朋友可以参考下
正文
Android实现Activity、Service与Broadcaster三大组件之间互相调用的方法详解
本文实例讲述了android实现activity、service与broadcaster三大组件之间互相调用的方法。分享给大家供大家参考,具体如下:
我们研究两个问题,
1、service如何通过broadcaster更改activity的一个textview。
(研究这个问题,考虑到service从服务器端获得消息之后,将msg返回给activity)
2、activity如何通过binder调用service的一个方法。
(研究这个问题,考虑到与服务器端交互的动作,打包至service,activity只呈现界面,调用service的方法)
结构图见如下:

效果图如下:

点击“start service”按钮,启动service,然后更改activity的ui。

点击“send msg to server”按钮调用service的方法,显示notificationbar
代码:
1、新建一个myservice类,继承service
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
package com.ljq.activity;import android.app.notification;import android.app.notificationmanager;import android.app.pendingintent;import android.app.service;import android.content.context;import android.content.intent;import android.graphics.color;import android.os.binder;import android.os.ibinder;public class myservice extends service { private notificationmanager notificationmanager = null; private final ibinder binder = new localbinder(); @override public void oncreate() { sendmsgtoactivty("service is oncreating.\n"); } @override public ibinder onbind(intent intent) { string msg = "activity is sendding message to service,\n service send msg to server!\n"; sendmsgtoactivty(msg); return binder; } /** * 把信息传递给activity * * @param msg */ private void sendmsgtoactivty(string msg) { intent intent = new intent("com.android.yao.msg"); intent.putextra("msg", msg); this.sendbroadcast(intent); } @override public void ondestroy() { super.ondestroy(); if(notificationmanager!=null){ notificationmanager.cancel(0); notificationmanager=null; } } /** * 在状态栏显示通知 * * @param msg */ private void shownotification(string msg) { notificationmanager = (notificationmanager) getsystemservice(context.notification_service); // 定义notification的各种属性 notification notification =new notification(r.drawable.icon, "a message coming!", system.currenttimemillis()); //flag_auto_cancel 该通知能被状态栏的清除按钮给清除掉 //flag_no_clear 该通知不能被状态栏的清除按钮给清除掉 //flag_ongoing_event 通知放置在正在运行 //flag_insistent 是否一直进行,比如音乐一直播放,知道用户响应 notification.flags |= notification.flag_ongoing_event; // 将此通知放到通知栏的"ongoing"即"正在运行"组中 notification.flags |= notification.flag_no_clear; // 表明在点击了通知栏中的"清除通知"后,此通知不清除,经常与flag_ongoing_event一起使用 notification.flags |= notification.flag_show_lights; //default_all 使用所有默认值,比如声音,震动,闪屏等等 //default_lights 使用默认闪光提示 //default_sounds 使用默认提示声音 //default_vibrate 使用默认手机震动,需加上<uses-permission android:name="android.permission.vibrate" />权限 notification.defaults = notification.default_lights; //叠加效果常量 //notification.defaults=notification.default_lights|notification.default_sound; notification.ledargb = color.blue; notification.ledonms =5000; //闪光时间,毫秒 // 设置通知的事件消息 //intent notificationintent =new intent(mainactivity.this, mainactivity.class); // 点击该通知后要跳转的activity intent notificationintent = new intent(getapplicationcontext(), mainactivity.class); // 加载类,如果直接通过类名,会在点击时重新加载页面,无法恢复最后页面状态。 notificationintent.setflags(intent.flag_activity_single_top); pendingintent contentitent = pendingintent.getactivity(this, 0, notificationintent, 0); notification.setlatesteventinfo(this, "message", "message:" + msg, contentitent); // 把notification传递给notificationmanager notificationmanager.notify(0, notification); } /** * 从activity获取信息 * * @param msg */ public void receivermsgtoactivity(string msg){ sendmsgtoactivty("\n receivermsgtoactivity:"+msg); } public void sendmsgtoserver(string msg) { shownotification(msg); } public class localbinder extends binder { public myservice getservice() { return myservice.this; } }} |
2、新建mybroadcastreceiver类,继承broadcastreceiver,用来发送intent启动服务
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package com.ljq.activity;import android.content.broadcastreceiver;import android.content.context;import android.content.intent;/** * 发送intent启动服务 * * @author jiqinlin * */public class mybroadcastreceiver extends broadcastreceiver { @override public void onreceive(context context, intent intent) { intent service = new intent(context, myservice.class); context.startservice(service); }} |
3、新建mainactivity类,其实是一个activity,用来呈现界面
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
package com.ljq.activity;import java.util.list;import android.app.activity;import android.app.activitymanager;import android.content.broadcastreceiver;import android.content.componentname;import android.content.context;import android.content.intent;import android.content.intentfilter;import android.content.serviceconnection;import android.os.bundle;import android.os.ibinder;import android.util.log;import android.view.view;import android.widget.textview;public class mainactivity extends activity implements view.onclicklistener { private string msg = ""; private textview txtmsg; private updatereceiver receiver; private myservice myservice; private final static string tag=mainactivity.class.getsimplename(); @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); txtmsg = (textview) this.findviewbyid(r.id.txtmsg); this.findviewbyid(r.id.btnstart).setonclicklistener(this); this.findviewbyid(r.id.btnsend).setonclicklistener(this); //订阅广播intent receiver = new updatereceiver(); intentfilter filter = new intentfilter(); filter.addaction("com.android.yao.msg"); this.registerreceiver(receiver, filter); //初始化时启动服务 //intent intent = new intent(mainactivity.this, myservice.class); //this.bindservice(intent, conn, bind_auto_create); } @override protected void ondestroy() { super.ondestroy(); //结束服务 if(conn!=null){ unbindservice(conn); myservice=null; } } public class updatereceiver extends broadcastreceiver { @override public void onreceive(context context, intent intent) { //获取service传过来的信息 msg = intent.getstringextra("msg"); txtmsg.append(msg); } } private serviceconnection conn = new serviceconnection() { @override public void onserviceconnected(componentname name, ibinder service) { myservice = ((myservice.localbinder) service).getservice(); log.i(tag, "onserviceconnected myservice: "+myservice); } @override public void onservicedisconnected(componentname name) { myservice = null; } }; @override public void onclick(view v) { intent intent = new intent(mainactivity.this, myservice.class); switch (v.getid()) { case r.id.btnstart: //判断服务是否启动 if(false==isservicerunning(this, myservice.class.getname())){ log.i(tag, "start "+myservice.class.getsimplename()+" service"); this.bindservice(intent, conn, bind_auto_create); } log.i(tag, myservice.class.getname()+" run status: "+isservicerunning(this, myservice.class.getname())); break; case r.id.btnsend: //判断服务是否启动 if(false==isservicerunning(this, myservice.class.getname())){ log.i(tag, "start "+myservice.class.getsimplename()+" service"); this.bindservice(intent, conn, bind_auto_create); } log.i(tag, myservice.class.getname()+" run status: "+isservicerunning(this, myservice.class.getname())); log.i(tag, "onclick myservice: "+myservice); //第一次启动服务时此处为null(小编认为虽然服务已启动成功,但是还没全部初始化) if(myservice!=null){ myservice.sendmsgtoserver("i am sending msg to server"); //从activity传递信息给service myservice.receivermsgtoactivity("this is a msg"); } break; } } /** * 判断服务是否正在运行 * * @param context * @param classname 判断的服务名字:包名+类名 * @return true在运行 false 不在运行 */ public static boolean isservicerunning(context context, string classname) { boolean isrunning = false; activitymanager activitymanager = (activitymanager) context .getsystemservice(context.activity_service); //获取所有的服务 list<activitymanager.runningserviceinfo> services= activitymanager.getrunningservices(integer.max_value); if(services!=null&&services.size()>0){ for(activitymanager.runningserviceinfo service : services){ if(classname.equals(service.service.getclassname())){ isrunning=true; break; } } } return isrunning; }} |
4、main.xml布局文件
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?xml version="1.0" encoding="utf-8"?><linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtmsg" /> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="start service" android:id="@+id/btnstart"/> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="send msg to server" android:id="@+id/btnsend"/> </linearlayout></linearlayout> |
5、清单文件androidmanifest.xml,用来配置组件等信息
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ljq.activity" android:versioncode="1" android:versionname="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".mainactivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> <service android:name=".myservice"/> <receiver android:name=".mybroadcastreceiver" /> </application> <uses-sdk android:minsdkversion="7" /></manifest> |
希望本文所述对大家android程序设计有所帮助。

发表评论