欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现Activity、Service与Broadcaster三大组件之间互相调用的方法详解

程序员文章站 2024-02-25 11:41:10
本文实例讲述了android实现activity、service与broadcaster三大组件之间互相调用的方法。分享给大家供大家参考,具体如下: 我们研究两个问题,...

本文实例讲述了android实现activity、service与broadcaster三大组件之间互相调用的方法。分享给大家供大家参考,具体如下:

我们研究两个问题,

1、service如何通过broadcaster更改activity的一个textview。
(研究这个问题,考虑到service从服务器端获得消息之后,将msg返回给activity)

2、activity如何通过binder调用service的一个方法。
(研究这个问题,考虑到与服务器端交互的动作,打包至service,activity只呈现界面,调用service的方法)

结构图见如下:

Android实现Activity、Service与Broadcaster三大组件之间互相调用的方法详解

效果图如下:

Android实现Activity、Service与Broadcaster三大组件之间互相调用的方法详解

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

Android实现Activity、Service与Broadcaster三大组件之间互相调用的方法详解

点击“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程序设计有所帮助。