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