例如:使用消息传递活动和服务之间的通信 [英] Example: Communication between Activity and Service using Messaging

查看:173
本文介绍了例如:使用消息传递活动和服务之间的通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法找到如何活动和服务之间发送消息的任何例子,我花了太多时间搞清楚了这一点。下面是一个例子项目供他人参考。

这个例子可以让你开始或直接停止服务,并分别绑定/从服务解除绑定。当服务运行时,它增加了一些在10 NBSP;赫兹。如果活动被绑定到服务,它会显示当前值。数据传输为整数,作为一个字符串,所以你可以看到如何做到这一点两种不同的方式。也有在将消息发送给该服务的活动按钮(改变增量者值)。

截图:

的Andr​​oidManifest.xml:

 < XML版本=1.0编码=UTF-8&GT?;
<舱单的xmlns:机器人=htt​​p://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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆