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类:

package com.example.servicecallback;



public class Person {



    private String name;



    public String getName() {

        return name;

    }



    public void setName(String name) {

        this.name = name;

    }



    @Override

    public String toString() {

        return "Person [name=" + name + "]";

    }



}
View Code

MainActiivty的布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context=".MainActivity" >



    <Button

        android:id="@+id/button1"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="next" />



    <TextView

        android:id="@+id/content"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="@string/hello_world" />



</LinearLayout>
View Code

OtherActivity的布局文件:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >



    <EditText

        android:id="@+id/edittext"

        android:layout_width="match_parent"

        android:layout_height="wrap_content" />



    <Button

        android:id="@+id/button1"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="submit" />



    <TextView

        android:id="@+id/content"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="content" />



</LinearLayout>
View Code

由于笔者的水平有限,如有错漏,请各位留言指正,感激不尽!

以上虽有借鉴别人的思想,但是源代码均为原创。请尊重笔者的劳动成果。如果转载,请注明出处,谢谢!

全文完

你可能感兴趣的:(Activity)