天天看点

Activity service 通信

前段时间工作太忙,所以android的学习落了下来。这两天休息礼拜,重新研究。

之前学习了socket通讯,其中在service一端通过发送notificationbar显示在终端的Activity上。

事实上这种方式对于客户体验上,是单一而不友好的。

下面,我们研究两个问题,

1、Service如何通过Broadcaster更改activity的一个TextView。

(研究这个问题,是因为考虑到Service从服务器端获得消息之后,将msg返回至activity)

2、Activity如何通过Binder调用Service的一个方法。

(研究这个问题,是因为考虑到,将所有与服务器端交互的动作,打包至Service,Activity只需呈现界面,调用Service的方法)

结构图见如下:

Activity service 通信

效果图如下:

点击start,启动Service,然后更改Activity的UI。

Activity service 通信

点击Send Message to Server调用Service的方法,显示NotificationBar

Activity service 通信
Activity service 通信

使用Binder要注意个的一个地方是:ServiceConnection,需要在ServiceConnection中,实例化一个Service,使之等于Activity调用的Service。注意看下面的红色代码。

Broadcaster的过滤词,注意看下面的蓝色代码。

程序:

YaoTestBro.java:

package com.android.Yao;

import android.app.Activity;

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.view.View;

import android.view.View.OnClickListener;

import android.widget.*;

public class YaoTestBro extends Activity implements OnClickListener{

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        txtmsg = (TextView)this.findViewById(R.id.txtmsg);

        this.findViewById(R.id.start).setOnClickListener(this);

        this.findViewById(R.id.sendmsg).setOnClickListener(this);    

        receiver = new UpdateReceiver();

        IntentFilter filter= new IntentFilter();

        filter.addAction("com.android.Yao.msg");

        this.registerReceiver(receiver, filter);

    }    

    private UpdateReceiver receiver;

    private TextView txtmsg;

    private Button btnstart;

    private Button btnstop;

    private String msg = "";

    private MyService mservice;

    public class UpdateReceiver extends BroadcastReceiver{

  @Override

  public void onReceive(Context context, Intent intent) {

   // TODO Auto-generated method stub

   msg = intent.getStringExtra("msg");

   txtmsg.append(msg);

  }     

    }

   private ServiceConnection conn = new ServiceConnection()

    {

  public void onServiceConnected(ComponentName name, IBinder service) {

   mservice = ((MyService.LocalBinder)service).getService();

  }

  public void onServiceDisconnected(ComponentName name) {

   mservice = null;

    };

 @Override

 public void onClick(View v) {

  // TODO Auto-generated method stub

  Intent intent=new Intent(YaoTestBro.this,MyService.class);

  switch(v.getId())

  {

   case R.id.start:

    this.bindService(intent, conn, BIND_AUTO_CREATE);

    break;

   case R.id.sendmsg:

    //可以在这里加一个判断,如果启动了Service则跳过这句

    this.bindService(intent, conn, BIND_AUTO_CREATE); 

    mservice.SendMsgtoServer("i am sending msg to server");

 }    

}

MyService.java:

import android.app.Notification;

import android.app.NotificationManager;

import android.app.PendingIntent;

import android.app.Service;

import android.os.Binder;

public class MyService extends Service{

 /*activity通过Ibinder调用service中的方法,

  * service发送消息至sever,得到反馈之后,

  * sever返回消息至service,

  * service通过broadcast更改activity界面。

  */

 public IBinder onBind(Intent arg0) {

  String msg = "Service:Activity is sendding message to service,\n Service send msg to server!\n";

  SendMsgtoActivty(msg);

  return mBinder;

 } 

    public void onCreate() {       

     SendMsgtoActivty("Service:Service is oncreating.\n");

 private void SendMsgtoActivty(String msg)

 {

  Intent intent=new Intent("com.android.Yao.msg");

  intent.putExtra("msg", msg);

  this.sendBroadcast(intent);

 }

    private void shownotification(String tab)

     NotificationManager barmanager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

     Notification msg=new Notification(android.R.drawable.stat_notify_chat,"A Message Coming!",System.currentTimeMillis());    

     PendingIntent contentIntent=PendingIntent.getActivity(this, 0, new Intent(this,YaoTestBro.class), PendingIntent.FLAG_ONE_SHOT); 

     msg.setLatestEventInfo(this,"Message" , "Message:"+tab, contentIntent);

     barmanager.notify(0, msg);

 public void SendMsgtoServer(String msg) {

  shownotification(msg);

 public class LocalBinder extends Binder {

  MyService getService(){

   return MyService.this;

 private final IBinder mBinder = new LocalBinder();

MyBroadcaster.java:

public class MyBroadcastreceiver extends BroadcastReceiver {

 public void onReceive(Context context, Intent intent) {

  Intent service = new Intent(context,MyService.class);

  context.startService(service);

这里有两个东西,一个是Broadcaster,一个是Binder。

Broadcaster有很广泛的应用,多数的广播是系统发起的,如地域变换、电量不足、来电来信等。

程序自己的广播,可以通过filter.addAction来进行删选。。。

Binder是一个类似于C#.net中的DataBinder的一个概念,

Activity-->打开Binder-->写数据-->Service-->打开Binder-->写数据-->Activity。

事实上,用Binder也可实现将值从Servcie传送至Activity。。有兴趣的同志可以自己学习学习。。。

贴一篇好文章:

<a href="http://blog.csdn.net/maxleng/archive/2010/04/15/5490770.aspx">http://blog.csdn.net/maxleng/archive/2010/04/15/5490770.aspx</a>

继续阅读