本文实例讲述了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程序设计有所帮助。