例如:使用消息传递活动和服务之间的通信 [英] Example: Communication between Activity and Service using Messaging
问题描述
我无法找到如何活动和服务之间发送消息的任何例子,我花了太多时间搞清楚了这一点。下面是一个例子项目供他人参考。
这个例子可以让你开始或直接停止服务,并分别绑定/从服务解除绑定。当服务运行时,它增加了一些在10 NBSP;赫兹。如果活动被绑定到服务
,它会显示当前值。数据传输为整数,作为一个字符串,所以你可以看到如何做到这一点两种不同的方式。也有在将消息发送给该服务的活动按钮(改变增量者值)。
截图:
的AndroidManifest.xml:
< XML版本=1.0编码=UTF-8&GT?;
<舱单的xmlns:机器人=http://schemas.android.com/apk/res/android
包=com.exampleservice
安卓版code =1
机器人:VERSIONNAME =1.0>
<应用机器人:图标=@可绘制/图标机器人:标签=@字符串/ APP_NAME>
<活动机器人:名称=。MainActivity
机器人:标签=@字符串/ APP_NAME>
<意向滤光器>
<作用机器人:名称=android.intent.action.MAIN/>
<类机器人:名称=android.intent.category.LAUNCHER/>
&所述; /意图滤光器>
< /活性GT;
<服务机器人:名称=。为MyService>< /服务>
< /用途>
<使用-SDK安卓的minSdkVersion =8/>
< /舱单>
资源\值\ strings.xml中:
< XML版本=1.0编码=UTF-8&GT?;
<资源>
<字符串名称=APP_NAME> ExampleService< /串>
<字符串名称=service_started物实施例服务启动< /串>
<字符串名称=SERVICE_LABEL物实施例服务标签和LT; /串>
< /资源>
资源\布局\ main.xml中:
< RelativeLayout的
机器人:ID =@ + ID / RelativeLayout01
机器人:layout_width =FILL_PARENT
机器人:layout_height =WRAP_CONTENT>
<按钮
机器人:ID =@ + ID / btnStart
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:文本=启动服务>
< /按钮>
<按钮
机器人:ID =@ + ID / btnStop
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:layout_alignParentRight =真
机器人:文本=停止服务>
< /按钮>
< / RelativeLayout的>
< RelativeLayout的
机器人:ID =@ + ID / RelativeLayout02
机器人:layout_width =FILL_PARENT
机器人:layout_height =WRAP_CONTENT>
<按钮
机器人:ID =@ + ID / btnBind
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:文本=绑定到服务>
< /按钮>
<按钮
机器人:ID =@ + ID / btnUnbind
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:layout_alignParentRight =真
机器人:文本=解除绑定服务>
< /按钮>
< / RelativeLayout的>
<的TextView
机器人:ID =@ + ID / textStatus
机器人:layout_width =FILL_PARENT
机器人:layout_height =WRAP_CONTENT
机器人:文本=状态会在这里
机器人:TEXTSIZE =24sp/>
<的TextView
机器人:ID =@ + ID / textIntValue
机器人:layout_width =FILL_PARENT
机器人:layout_height =WRAP_CONTENT
机器人:文本=整数值超出此处
机器人:TEXTSIZE =24sp/>
<的TextView
机器人:ID =@ + ID / textStrValue
机器人:layout_width =FILL_PARENT
机器人:layout_height =WRAP_CONTENT
机器人:文本=字符串值放这里
机器人:TEXTSIZE =24sp/>
< RelativeLayout的
机器人:ID =@ + ID / RelativeLayout03
机器人:layout_width =FILL_PARENT
机器人:layout_height =WRAP_CONTENT>
<按钮
机器人:ID =@ + ID / btnUpby1
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:文本=加1>
< /按钮>
<按钮
机器人:ID =@ + ID / btnUpby10
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:layout_alignParentRight =真
机器人:文本=增量为10>
< /按钮>
< / RelativeLayout的>
的src \ com.exampleservice \ MainActivity.java:
包com.exampleservice;
进口android.app.Activity;
进口android.content.ComponentName;
进口android.content.Context;
进口android.content.Intent;
进口android.content.ServiceConnection;
进口android.os.Bundle;
进口android.os.Handler;
进口android.os.IBinder;
进口android.os.Message;
进口android.os.Messenger;
进口android.os.RemoteException;
进口android.util.Log;
进口android.view.View;
进口android.view.View.OnClickListener;
进口android.widget.Button;
进口android.widget.TextView;
公共类MainActivity延伸活动{
按钮btnStart,btnStop,btnBind,btnUnbind,btnUpby1,btnUpby10;
TextView的textStatus,textIntValue,textStrValue;
信使MSERVICE = NULL;
布尔mIsBound;
最后的使者mMessenger =新使者(新IncomingHandler());
类IncomingHandler扩展处理程序{
@覆盖
公共无效的handleMessage(信息MSG){
开关(msg.what){
案例MyService.MSG_SET_INT_VALUE:
textIntValue.setText(内部消息:+ msg.arg1);
打破;
案例MyService.MSG_SET_STRING_VALUE:
字符串STR1 = msg.getData()的getString(STR1)。
textStrValue.setText(海峡消息:+ STR1);
打破;
默认:
super.handleMessage(MSG);
}
}
}
私人ServiceConnection mConnection =新ServiceConnection(){
公共无效onServiceConnected(组件名的className,服务的IBinder){
MSERVICE =新的信使(服务);
textStatus.setText(附。);
尝试 {
消息味精= Message.obtain(空,MyService.MSG_REGISTER_CLIENT);
msg.replyTo = mMessenger;
mService.send(MSG);
}
赶上(RemoteException的E){
//在这种情况下,服务已经崩溃之前,我们甚至可以用它做什么
}
}
公共无效onServiceDisconnected(组件名的className){
//这就是所谓的用时,该服务的连接已断开意外 - 进程崩溃。
MSERVICE = NULL;
textStatus.setText(断开);
}
};
@覆盖
公共无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.main);
btnStart =(按钮)findViewById(R.id.btnStart);
btnStop =(按钮)findViewById(R.id.btnStop);
btnBind =(按钮)findViewById(R.id.btnBind);
btnUnbind =(按钮)findViewById(R.id.btnUnbind);
textStatus =(TextView中)findViewById(R.id.textStatus);
textIntValue =(TextView中)findViewById(R.id.textIntValue);
textStrValue =(TextView中)findViewById(R.id.textStrValue);
btnUpby1 =(按钮)findViewById(R.id.btnUpby1);
btnUpby10 =(按钮)findViewById(R.id.btnUpby10);
btnStart.setOnClickListener(btnStartListener);
btnStop.setOnClickListener(btnStopListener);
btnBind.setOnClickListener(btnBindListener);
btnUnbind.setOnClickListener(btnUnbindListener);
btnUpby1.setOnClickListener(btnUpby1Listener);
btnUpby10.setOnClickListener(btnUpby10Listener);
restoreMe(savedInstanceState);
CheckIfServiceIsRunning();
}
@覆盖
保护无效的onSaveInstanceState(包outState){
super.onSaveInstanceState(outState);
outState.putString(textStatus,textStatus.getText()的toString());
outState.putString(textIntValue,textIntValue.getText()的toString());
outState.putString(textStrValue,textStrValue.getText()的toString());
}
私人无效restoreMe(包状态){
如果(状态!= NULL){
textStatus.setText(state.getString(textStatus));
textIntValue.setText(state.getString(textIntValue));
textStrValue.setText(state.getString(textStrValue));
}
}
私人无效CheckIfServiceIsRunning(){
//如果服务正在运行的活动开始的时候,我们要自动绑定到它。
如果(MyService.isRunning()){
doBindService();
}
}
私人OnClickListener btnStartListener =新OnClickListener(){
公共无效的onClick(视图v){
startService(新意图(MainActivity.this,MyService.class));
}
};
私人OnClickListener btnStopListener =新OnClickListener(){
公共无效的onClick(视图v){
doUnbindService();
stopService(新意图(MainActivity.this,MyService.class));
}
};
私人OnClickListener btnBindListener =新OnClickListener(){
公共无效的onClick(视图v){
doBindService();
}
};
私人OnClickListener btnUnbindListener =新OnClickListener(){
公共无效的onClick(视图v){
doUnbindService();
}
};
私人OnClickListener btnUpby1Listener =新OnClickListener(){
公共无效的onClick(视图v){
sendMessageToService(1);
}
};
私人OnClickListener btnUpby10Listener =新OnClickListener(){
公共无效的onClick(视图v){
sendMessageToService(10);
}
};
私人无效sendMessageToService(INT intvaluetosend){
如果(mIsBound){
如果(MSERVICE!= NULL){
尝试 {
消息味精= Message.obtain(NULL,MyService.MSG_SET_INT_VALUE,intvaluetosend,0);
msg.replyTo = mMessenger;
mService.send(MSG);
}
赶上(RemoteException的E){
}
}
}
}
无效doBindService(){
bindService(新意图(这一点,MyService.class),mConnection,Context.BIND_AUTO_CREATE);
mIsBound = TRUE;
textStatus.setText(绑定。);
}
无效doUnbindService(){
如果(mIsBound){
//如果我们得到的服务,因此用它注册,那么现在是注销的时间。
如果(MSERVICE!= NULL){
尝试 {
消息味精= Message.obtain(空,MyService.MSG_UNREGISTER_CLIENT);
msg.replyTo = mMessenger;
mService.send(MSG);
}
赶上(RemoteException的E){
//没有什么特别的,我们需要做的,如果该服务已崩溃。
}
}
//分离我们的现有连接。
unbindService(mConnection);
mIsBound = FALSE;
textStatus.setText(解除绑定。);
}
}
@覆盖
保护无效的onDestroy(){
super.onDestroy();
尝试 {
doUnbindService();
}
捕获(的Throwable T){
Log.e(MainActivity,无法从服务解除绑定,T);
}
}
}
的src \ com.exampleservice \ MyService.java:
包com.exampleservice;
进口的java.util.ArrayList;
进口java.util.Timer中;
进口java.util.TimerTask中;
进口android.app.Notification;
进口android.app.NotificationManager;
进口android.app.PendingIntent;
进口android.app.Service;
进口android.content.Intent;
进口android.os.Bundle;
进口android.os.Handler;
进口android.os.IBinder;
进口android.os.Message;
进口android.os.Messenger;
进口android.os.RemoteException;
进口android.util.Log;
公共类的MyService延伸服务{
私人NotificationManager处;
私人定时器定时=新的Timer();
私人诠释柜台= 0,incrementby = 1;
私有静态布尔isRunning = FALSE;
ArrayList的<信使> mClients =新的ArrayList<信使>(); //跟踪所有目前注册客户端。
INT mValue = 0; //保存由客户端设置一个值。
静态最终诠释MSG_REGISTER_CLIENT = 1;
静态最终诠释MSG_UNREGISTER_CLIENT = 2;
静态最终诠释MSG_SET_INT_VALUE = 3;
静态最终诠释MSG_SET_STRING_VALUE = 4;
最后的使者mMessenger =新使者(新IncomingHandler()); //目标,我们发布的客户端发送信息到IncomingHandler。
@覆盖
公众的IBinder onBind(意向意图){
返回mMessenger.getBinder();
}
类IncomingHandler扩展了Handler {//来自客户端的邮件处理程序。
@覆盖
公共无效的handleMessage(信息MSG){
开关(msg.what){
案例MSG_REGISTER_CLIENT:
mClients.add(msg.replyTo);
打破;
案例MSG_UNREGISTER_CLIENT:
mClients.remove(msg.replyTo);
打破;
案例MSG_SET_INT_VALUE:
incrementby = msg.arg1;
打破;
默认:
super.handleMessage(MSG);
}
}
}
私人无效sendMessageToUI(INT intvaluetosend){
的for(int i = mClients.size() - 1; I> = 0;我 - ){
尝试 {
//发送数据作为一个整数
mClients.get(ⅰ)。发送(Message.obtain(空,MSG_SET_INT_VALUE,intvaluetosend,0));
//发送数据作为一个字符串
叠B =新包();
b.putString(STR1,AB+ intvaluetosend +CD);
消息味精= Message.obtain(空,MSG_SET_STRING_VALUE);
msg.setData(B);
mClients.get(ⅰ)。发送(MSG);
}
赶上(RemoteException的E){
//客户端已经死了。从列表中删除;我们是从后向前经历列表,所以这是确保安全的内循环。
mClients.remove(ⅰ);
}
}
}
@覆盖
公共无效的onCreate(){
super.onCreate();
Log.i(为MyService,服务启动。);
showNotification();
timer.scheduleAtFixedRate(新的TimerTask(){公共无效的run(){onTimerTick();}},0,100L);
isRunning = TRUE;
}
私人无效showNotification(){
纳米=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
//在此示例中,我们将使用相同的文字为股票和扩展的通知
CharSequence的文字=的getText(R.string.service_started);
//设置图标,滚动文字和时间戳
通知通知=新的通知(R.drawable.icon,文字,System.currentTimeMillis的());
//该PendingIntent来,如果用户选择此通知发布我们的活动
PendingIntent contentIntent = PendingIntent.getActivity(此,0,新意图(本,MainActivity.class),0);
//设置为显示在通知面板的意见信息。
notification.setLatestEventInfo(这一点,gettext的(R.string.service_label),文本,contentIntent);
//发送通知。
//我们使用一个布局ID,因为它是唯一的编号。我们用它后来取消。
nm.notify(R.string.service_started,通知);
}
@覆盖
公众诠释onStartCommand(意向意图,诠释标志,诠释startId){
Log.i(为MyService,收到的起始ID+ startId +:+意图);
返回START_STICKY; //运行,直到明确停止。
}
公共静态布尔isRunning()
{
返回isRunning;
}
私人无效onTimerTick(){
Log.i(TimerTick,定时做的工作。+计数器);
尝试 {
计数器+ = incrementby;
sendMessageToUI(柜);
}
捕获(的Throwable T){//你应该总是最终赶在计时器任务的所有异常。
Log.e(TimerTick,时钟滴答失败,T);
}
}
@覆盖
公共无效的onDestroy(){
super.onDestroy();
如果(定时器!= NULL){timer.cancel();}
计数器= 0;
nm.cancel(R.string.service_started); //取消永久通知。
Log.i(为MyService,服务已停止。);
isRunning = FALSE;
}
}
看<一href="http://developer.android.com/reference/android/app/Service.html#LocalServiceSample">LocalService例如。
您服务
返回到消费者谁打电话 onBind
自己的一个实例。然后,您可以直接与服务,如互动注册自己的监听器接口的服务,这样你可以得到的回调。
I couldn't find any examples of how to send messages between an activity and a service, and I have spent far too many hours figuring this out. Here is an example project for others to reference.
This example allows you to start or stop a service directly, and separately bind/unbind from the service. When the service is running, it increments a number at 10 Hz. If the activity is bound to the Service
, it will display the current value. Data is transferred as an Integer and as a String so you can see how to do that two different ways. There are also buttons in the activity to send messages to the service (changes the increment-by value).
Screenshot:
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exampleservice"
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"></service>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>
res\values\strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ExampleService</string>
<string name="service_started">Example Service started</string>
<string name="service_label">Example Service Label</string>
</resources>
res\layout\main.xml:
<RelativeLayout
android:id="@+id/RelativeLayout01"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Service" >
</Button>
<Button
android:id="@+id/btnStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Stop Service" >
</Button>
</RelativeLayout>
<RelativeLayout
android:id="@+id/RelativeLayout02"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/btnBind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bind to Service" >
</Button>
<Button
android:id="@+id/btnUnbind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Unbind from Service" >
</Button>
</RelativeLayout>
<TextView
android:id="@+id/textStatus"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Status Goes Here"
android:textSize="24sp" />
<TextView
android:id="@+id/textIntValue"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Integer Value Goes Here"
android:textSize="24sp" />
<TextView
android:id="@+id/textStrValue"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="String Value Goes Here"
android:textSize="24sp" />
<RelativeLayout
android:id="@+id/RelativeLayout03"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/btnUpby1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Increment by 1" >
</Button>
<Button
android:id="@+id/btnUpby10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Increment by 10" >
</Button>
</RelativeLayout>
src\com.exampleservice\MainActivity.java:
package com.exampleservice;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
Button btnStart, btnStop, btnBind, btnUnbind, btnUpby1, btnUpby10;
TextView textStatus, textIntValue, textStrValue;
Messenger mService = null;
boolean mIsBound;
final Messenger mMessenger = new Messenger(new IncomingHandler());
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MyService.MSG_SET_INT_VALUE:
textIntValue.setText("Int Message: " + msg.arg1);
break;
case MyService.MSG_SET_STRING_VALUE:
String str1 = msg.getData().getString("str1");
textStrValue.setText("Str Message: " + str1);
break;
default:
super.handleMessage(msg);
}
}
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mService = new Messenger(service);
textStatus.setText("Attached.");
try {
Message msg = Message.obtain(null, MyService.MSG_REGISTER_CLIENT);
msg.replyTo = mMessenger;
mService.send(msg);
}
catch (RemoteException e) {
// In this case the service has crashed before we could even do anything with it
}
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been unexpectedly disconnected - process crashed.
mService = null;
textStatus.setText("Disconnected.");
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnStart = (Button)findViewById(R.id.btnStart);
btnStop = (Button)findViewById(R.id.btnStop);
btnBind = (Button)findViewById(R.id.btnBind);
btnUnbind = (Button)findViewById(R.id.btnUnbind);
textStatus = (TextView)findViewById(R.id.textStatus);
textIntValue = (TextView)findViewById(R.id.textIntValue);
textStrValue = (TextView)findViewById(R.id.textStrValue);
btnUpby1 = (Button)findViewById(R.id.btnUpby1);
btnUpby10 = (Button)findViewById(R.id.btnUpby10);
btnStart.setOnClickListener(btnStartListener);
btnStop.setOnClickListener(btnStopListener);
btnBind.setOnClickListener(btnBindListener);
btnUnbind.setOnClickListener(btnUnbindListener);
btnUpby1.setOnClickListener(btnUpby1Listener);
btnUpby10.setOnClickListener(btnUpby10Listener);
restoreMe(savedInstanceState);
CheckIfServiceIsRunning();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("textStatus", textStatus.getText().toString());
outState.putString("textIntValue", textIntValue.getText().toString());
outState.putString("textStrValue", textStrValue.getText().toString());
}
private void restoreMe(Bundle state) {
if (state!=null) {
textStatus.setText(state.getString("textStatus"));
textIntValue.setText(state.getString("textIntValue"));
textStrValue.setText(state.getString("textStrValue"));
}
}
private void CheckIfServiceIsRunning() {
//If the service is running when the activity starts, we want to automatically bind to it.
if (MyService.isRunning()) {
doBindService();
}
}
private OnClickListener btnStartListener = new OnClickListener() {
public void onClick(View v){
startService(new Intent(MainActivity.this, MyService.class));
}
};
private OnClickListener btnStopListener = new OnClickListener() {
public void onClick(View v){
doUnbindService();
stopService(new Intent(MainActivity.this, MyService.class));
}
};
private OnClickListener btnBindListener = new OnClickListener() {
public void onClick(View v){
doBindService();
}
};
private OnClickListener btnUnbindListener = new OnClickListener() {
public void onClick(View v){
doUnbindService();
}
};
private OnClickListener btnUpby1Listener = new OnClickListener() {
public void onClick(View v){
sendMessageToService(1);
}
};
private OnClickListener btnUpby10Listener = new OnClickListener() {
public void onClick(View v){
sendMessageToService(10);
}
};
private void sendMessageToService(int intvaluetosend) {
if (mIsBound) {
if (mService != null) {
try {
Message msg = Message.obtain(null, MyService.MSG_SET_INT_VALUE, intvaluetosend, 0);
msg.replyTo = mMessenger;
mService.send(msg);
}
catch (RemoteException e) {
}
}
}
}
void doBindService() {
bindService(new Intent(this, MyService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
textStatus.setText("Binding.");
}
void doUnbindService() {
if (mIsBound) {
// If we have received the service, and hence registered with it, then now is the time to unregister.
if (mService != null) {
try {
Message msg = Message.obtain(null, MyService.MSG_UNREGISTER_CLIENT);
msg.replyTo = mMessenger;
mService.send(msg);
}
catch (RemoteException e) {
// There is nothing special we need to do if the service has crashed.
}
}
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
textStatus.setText("Unbinding.");
}
}
@Override
protected void onDestroy() {
super.onDestroy();
try {
doUnbindService();
}
catch (Throwable t) {
Log.e("MainActivity", "Failed to unbind from the service", t);
}
}
}
src\com.exampleservice\MyService.java:
package com.exampleservice;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
public class MyService extends Service {
private NotificationManager nm;
private Timer timer = new Timer();
private int counter = 0, incrementby = 1;
private static boolean isRunning = false;
ArrayList<Messenger> mClients = new ArrayList<Messenger>(); // Keeps track of all current registered clients.
int mValue = 0; // Holds last value set by a client.
static final int MSG_REGISTER_CLIENT = 1;
static final int MSG_UNREGISTER_CLIENT = 2;
static final int MSG_SET_INT_VALUE = 3;
static final int MSG_SET_STRING_VALUE = 4;
final Messenger mMessenger = new Messenger(new IncomingHandler()); // Target we publish for clients to send messages to IncomingHandler.
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
class IncomingHandler extends Handler { // Handler of incoming messages from clients.
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REGISTER_CLIENT:
mClients.add(msg.replyTo);
break;
case MSG_UNREGISTER_CLIENT:
mClients.remove(msg.replyTo);
break;
case MSG_SET_INT_VALUE:
incrementby = msg.arg1;
break;
default:
super.handleMessage(msg);
}
}
}
private void sendMessageToUI(int intvaluetosend) {
for (int i=mClients.size()-1; i>=0; i--) {
try {
// Send data as an Integer
mClients.get(i).send(Message.obtain(null, MSG_SET_INT_VALUE, intvaluetosend, 0));
//Send data as a String
Bundle b = new Bundle();
b.putString("str1", "ab" + intvaluetosend + "cd");
Message msg = Message.obtain(null, MSG_SET_STRING_VALUE);
msg.setData(b);
mClients.get(i).send(msg);
}
catch (RemoteException e) {
// The client is dead. Remove it from the list; we are going through the list from back to front so this is safe to do inside the loop.
mClients.remove(i);
}
}
}
@Override
public void onCreate() {
super.onCreate();
Log.i("MyService", "Service Started.");
showNotification();
timer.scheduleAtFixedRate(new TimerTask(){ public void run() {onTimerTick();}}, 0, 100L);
isRunning = true;
}
private void showNotification() {
nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// In this sample, we'll use the same text for the ticker and the expanded notification
CharSequence text = getText(R.string.service_started);
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.icon, text, System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, getText(R.string.service_label), text, contentIntent);
// Send the notification.
// We use a layout id because it is a unique number. We use it later to cancel.
nm.notify(R.string.service_started, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("MyService", "Received start id " + startId + ": " + intent);
return START_STICKY; // run until explicitly stopped.
}
public static boolean isRunning()
{
return isRunning;
}
private void onTimerTick() {
Log.i("TimerTick", "Timer doing work." + counter);
try {
counter += incrementby;
sendMessageToUI(counter);
}
catch (Throwable t) { //you should always ultimately catch all exceptions in timer tasks.
Log.e("TimerTick", "Timer Tick Failed.", t);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (timer != null) {timer.cancel();}
counter=0;
nm.cancel(R.string.service_started); // Cancel the persistent notification.
Log.i("MyService", "Service Stopped.");
isRunning = false;
}
}
Look at the LocalService example.
Your Service
returns an instance of itself to consumers who call onBind
. Then you can directly interact with the service, e.g. registering your own listener interface with the service, so that you can get callbacks.
这篇关于例如:使用消息传递活动和服务之间的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!