Android中Service与多个Activity通信

Android中Service与多个Activity通信

由于项目需要,我们有时候需要在service中处理耗时操作,然后将结果发送给activity以更新状态。通常情况下,我们只需要在一个service与一个activity之间通信,通常这种情况下,我们使用最多的是通过回调接口。具体做法是在service中定义一个接口,在activity中实现改接口,并通过bindservice来传入。实现方式很简单,在此不再赘述。

当需要将service中的结果一次发送给多个activity时,我们又该如何实现呢?经过多个项目的积累,总结了三种实现的方式。分别是 回调接口、广播接收者和观察者模式 。

1.回调接口的方式 ,与单个service与单个activity通信类似,只是将service中的接口变为接口的集合,每个需要通信的activity都实现接口,然后在获取结果后,循环调用集合中的实现类,来与多个activity进行通信,代码如下:

Service类:

package com.example.servicecallback;

import java.util.ArrayList;
import java.util.List;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;

public class ContentService extends Service {

	//回调接口的集合
	private List<Callback> list;

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return new LocalBinder();
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		list = new ArrayList<Callback>();
	}

	public final class LocalBinder extends Binder {
		public ContentService getService() {
			return ContentService.this;
		}
	}

	/**
	 * 回调接口
	 * @author Ivan Xu
	 *
	 */
	public interface Callback {
		public void getPerson(Person person);
	}

	/**
	 * 往回调接口集合中添加一个实现类
	 * @param callback
	 */
	public void addCallback(Callback callback) {
		list.add(callback);
	}

	public void asyncSendPerson(final String name) {
		// 休息5秒,模拟异步任务
		new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				handler.sendMessage(handler.obtainMessage(0, name));
			}
		}).start();
	}

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			String name = (String) msg.obj;
			Log.i("ContentService", "---name-->" + name);
			Person person = new Person();
			person.setName(name);
			Log.i("ContentService", "---list.size()-->" + list.size());
			Log.i("ContentService", "---person-->" + person.toString());
			//遍历集合,通知所有的实现类,即activity
			for (int i = 0; i < list.size(); i++) {
				list.get(i).getPerson(person);
			}
		}
	};
}

View Code

第一个activity:

package com.example.servicecallback;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import com.example.servicecallback.ContentService.Callback;
import com.example.servicecallback.ContentService.LocalBinder;

public class MainActivity extends Activity implements Callback {

	private MyServiceConn conn;
	private ContentService service;
	private TextView mContent;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		conn=new MyServiceConn();
		bindService(new Intent(this, ContentService.class), conn,
				BIND_AUTO_CREATE);

		mContent = (TextView) findViewById(R.id.content);

		this.findViewById(R.id.button1).setOnClickListener(
				new OnClickListener() {
					@Override
					public void onClick(View v) {
						// TODO Auto-generated method stub
						startActivity(new Intent(MainActivity.this,
								OtherActivity.class));
					}
				});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public class MyServiceConn implements ServiceConnection {

		@Override
		public void onServiceConnected(ComponentName name, IBinder binder) {
			service = ((LocalBinder) binder).getService();
			//将当前activity添加到接口集合中
			service.addCallback(MainActivity.this);
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			service = null;
		}
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		unbindService(conn);
	}

	/**
	 * 获取回调的内容,更新UI
	 */
	@Override
	public void getPerson(Person person) {
		// TODO Auto-generated method stub
		mContent.setText(person.toString());
	}
}

View Code

第二个activity:

package com.example.servicecallback;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.example.servicecallback.ContentService.Callback;
import com.example.servicecallback.ContentService.LocalBinder;
import com.example.servicecallback.MainActivity.MyServiceConn;

public class OtherActivity extends Activity implements Callback {

	private ContentService service;
	private TextView mContent;
	private Button mSubmit;
	private EditText mEditText;
	private ServiceConnection conn;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);

		setContentView(R.layout.other);

		mEditText = (EditText) findViewById(R.id.edittext);
		mSubmit = (Button) findViewById(R.id.button1);
		mContent = (TextView) findViewById(R.id.content);

		mSubmit.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				String name = mEditText.getText().toString();
				service.asyncSendPerson(name);
			}
		});

		
		conn=new MyServiceConn();
		bindService(new Intent(OtherActivity.this, ContentService.class), conn,
				BIND_AUTO_CREATE);

	}

	public final class MyServiceConn implements ServiceConnection {
		@Override
		public void onServiceConnected(ComponentName name, IBinder binder) {
			// TODO Auto-generated method stub
			service = ((LocalBinder) binder).getService();
			//将当前activity添加到接口集合中
			service.addCallback(OtherActivity.this);
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			service = null;
		}
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		unbindService(conn);
	}

	/**
	 * 获取回调的内容,更新UI
	 */
	@Override
	public void getPerson(Person person) {
		// TODO Auto-generated method stub
		mContent.setText(person.toString());
	}
}

View Code

2.通过广播接收者 ,在service中执行完耗时操作后,将结果以广播的形式发送,在所有的activity中注册广播,接收到结果后更新UI,这种方式比较简单,也是笔者比较推荐的方式。因为耗时的操作结果不需要以handler的方式发送到主线程,可以直接在子线程中发送广播,接收者始终运行在主线程中。代码如下:

Service类:

package com.example.servicecallback;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class ContentService extends Service {


	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return new LocalBinder();
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
	}

	public final class LocalBinder extends Binder {
		public ContentService getService() {
			return ContentService.this;
		}
	}

	public void asyncSendPerson(final String name) {
		// 休息5秒,模拟异步任务
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				//可以在子线程中直接发送广播
				sendContentBroadcast(name);
			}
		}).start();
	}

	/**
	 * 发送广播
	 * @param name
	 */
	protected void sendContentBroadcast(String name) {
		// TODO Auto-generated method stub
		Intent intent=new Intent();
		intent.setAction("com.example.servicecallback.content");
		intent.putExtra("name", name);
		sendBroadcast(intent);
	}
}

View Code

第一个activity:

package com.example.servicecallback;

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.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MainActivity extends Activity {

	private MyServiceConn conn;
	private TextView mContent;
	private ContentReceiver mReceiver;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		conn = new MyServiceConn();
		bindService(new Intent(this, ContentService.class), conn,
				BIND_AUTO_CREATE);

		mContent = (TextView) findViewById(R.id.content);

		this.findViewById(R.id.button1).setOnClickListener(
				new OnClickListener() {
					@Override
					public void onClick(View v) {
						// TODO Auto-generated method stub
						startActivity(new Intent(MainActivity.this,
								OtherActivity.class));
					}
				});

		
		doRegisterReceiver();
	}

	/**
	 * 注册广播接收者
	 */
	private void doRegisterReceiver() {
		mReceiver=new ContentReceiver();
		IntentFilter filter = new IntentFilter(
				"com.example.servicecallback.content");
		registerReceiver(mReceiver, filter);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public class MyServiceConn implements ServiceConnection {

		@Override
		public void onServiceConnected(ComponentName name, IBinder binder) {
			// service = ((LocalBinder) binder).getService();
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			// service = null;
		}
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		unbindService(conn);
		if (mReceiver!=null) {
			unregisterReceiver(mReceiver);
		}
	}

	public class ContentReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			String name = intent.getStringExtra("name");
			Person person = new Person();
			person.setName(name);
			mContent.setText(person.toString());
		}
	}
}

View Code

另一个activity:

package com.example.servicecallback;

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.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.example.servicecallback.ContentService.LocalBinder;

public class OtherActivity extends Activity {

	private ContentService service;
	private TextView mContent;
	private Button mSubmit;
	private EditText mEditText;
	private ServiceConnection conn;
	private ContentReceiver mReceiver;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.other);

		mEditText = (EditText) findViewById(R.id.edittext);
		mSubmit = (Button) findViewById(R.id.button1);
		mContent = (TextView) findViewById(R.id.content);

		mSubmit.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				String name = mEditText.getText().toString();
				service.asyncSendPerson(name);
			}
		});

		
		conn=new MyServiceConn();
		bindService(new Intent(OtherActivity.this, ContentService.class), conn,
				BIND_AUTO_CREATE);

		doRegisterReceiver();
	}

	private void doRegisterReceiver() {
		mReceiver=new ContentReceiver();
		IntentFilter filter = new IntentFilter(
				"com.example.servicecallback.content");
		registerReceiver(mReceiver, filter);
	}
	
	public final class MyServiceConn implements ServiceConnection {
		@Override
		public void onServiceConnected(ComponentName name, IBinder binder) {
			service = ((LocalBinder) binder).getService();
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			service = null;
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		unbindService(conn);
		if (mReceiver!=null) {
			unregisterReceiver(mReceiver);
		}
	}

	public class ContentReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			String name = intent.getStringExtra("name");
			Person person = new Person();
			person.setName(name);
			mContent.setText(person.toString());
		}
	}
}

View Code

3.使用观察者模式 ,service为被观察者,所以的activity为观察者,当service中的内容发生改变时,通知所有的activity来更新,代码如下:

Service类:

package com.example.servicecallback;

import java.util.Observable;
import java.util.Observer;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;

public class ContentService extends Service {

	//被观察者
	private MyObservable mObservable;

	@Override
	public IBinder onBind(Intent arg0) {
		return new LocalBinder();
	}

	@Override
	public void onCreate() {
		super.onCreate();
		mObservable = new MyObservable();
	}

	public final class LocalBinder extends Binder {
		public ContentService getService() {
			return ContentService.this;
		}
	}

	public void asyncSendPerson(final String name) {
		// 休息5秒,模拟异步任务
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				handler.sendMessage(handler.obtainMessage(0, name));
			}
		}).start();
	}

	/**
	 * 添加观察者
	 * @param observer
	 */
	public void addObserver(Observer observer) {
		mObservable.addObserver(observer);
	}

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			String name = (String) msg.obj;
			Person person = new Person();
			person.setName(name);
			//通知更新
			mObservable.notifyChanged(person);
		}
	};

	public class MyObservable extends Observable {
		
		public void notifyChanged(Object object) {
			this.setChanged();
			this.notifyObservers(object);
		}
	}
}

View Code

第一个activity:

package com.example.servicecallback;

import java.util.Observable;
import java.util.Observer;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

import com.example.servicecallback.ContentService.LocalBinder;

public class MainActivity extends Activity implements Observer {

	private MyServiceConn conn;
	private TextView mContent;
	private ContentService mService;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		conn = new MyServiceConn();
		bindService(new Intent(this, ContentService.class), conn,
				BIND_AUTO_CREATE);

		mContent = (TextView) findViewById(R.id.content);

		this.findViewById(R.id.button1).setOnClickListener(
				new OnClickListener() {
					@Override
					public void onClick(View v) {
						startActivity(new Intent(MainActivity.this,
								OtherActivity.class));
					}
				});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public class MyServiceConn implements ServiceConnection {

		@Override
		public void onServiceConnected(ComponentName name, IBinder binder) {
			mService = ((LocalBinder) binder).getService();
			//将当前activity添加为观察者
			mService.addObserver(MainActivity.this);
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			mService = null;
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		unbindService(conn);
	}

	//更新UI
	@Override
	public void update(Observable observable, Object data) {
		Person person = (Person) data;
		mContent.setText(person.toString());
	}

}

View Code

第二个activity:

package com.example.servicecallback;

import java.util.Observable;
import java.util.Observer;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.example.servicecallback.ContentService.LocalBinder;

public class OtherActivity extends Activity implements Observer {

	private ContentService service;
	private TextView mContent;
	private Button mSubmit;
	private EditText mEditText;
	private ServiceConnection conn;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.other);

		mEditText = (EditText) findViewById(R.id.edittext);
		mSubmit = (Button) findViewById(R.id.button1);
		mContent = (TextView) findViewById(R.id.content);

		mSubmit.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				String name = mEditText.getText().toString();
				service.asyncSendPerson(name);
			}
		});

		conn = new MyServiceConn();
		bindService(new Intent(OtherActivity.this, ContentService.class), conn,
				BIND_AUTO_CREATE);

	}

	public final class MyServiceConn implements ServiceConnection {
		@Override
		public void onServiceConnected(ComponentName name, IBinder binder) {
			service = ((LocalBinder) binder).getService();
			//将当前activity添加为观察者
			service.addObserver(OtherActivity.this);
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			service = null;
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		unbindService(conn);
	}

	//更新UI
	@Override
	public void update(Observable observable, Object data) {
		// TODO Auto-generated method stub
		Person person=(Person) data;
		
		mContent.setText(person.toString());
	}
}

View Code

附上其他相关代码,三种方式都一样:

Person类:

相关微博 ()
我来评几句
错误
登录后评论

已发表评论数(0)

没有更多评论了^^
评论加载失败, 重新加载
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值