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
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启动服务
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,用来呈现界面
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布局文件
<?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,用来配置组件等信息
<?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相关内容感兴趣的读者可查看本站专题:《android调试技巧与常见问题解决方法汇总》、《android开发入门与进阶教程》、《android多媒体操作技巧汇总(音频,视频,录音等)》、《android基本组件用法总结》、《android视图view技巧总结》、《android布局layout技巧总结》及《android控件用法总结》
希望本文所述对大家android程序设计有所帮助。