美文网首页IT梦AndroidAndroid高级进阶知识
Activity 与 Service 通信方式 总结

Activity 与 Service 通信方式 总结

作者: XP_Aaron | 来源:发表于2015-07-18 10:02 被阅读3636次

    通信方式

    1. binder + 回调(listener)

    主要思路:Acitivity 将实例传入 Service,同时利用回调更新UI

    2. binder + Handler

    主要思路:Service 持有 Activity的Handler 对象,Service 通过往该Handler send message 的方式,达到通信的目的。

    3. 广播 (推荐LocalBroadcastManager)

    主要思路:利用系统的LocalBroadcastManager,Service send message, Activity receive message;

    4. 开源组件(EventBus,otto)

    主要思路:利用反射或者注释的方式实现对注册类的注册,然后遍历当前的注册表,通过key进行查询,然后dispatch,调用相应的事件处理方法。(不同的开源框架实现有所区别)

    5. AIDL

    主要思路://TODO

    总结

    目前Android 组件之间主流的通信方式如上所述的5种,哪种对于项目更加合适,需要考虑的适用情况有:

    1. 进程内通信还是进程间通信
    2. 一对一通信,还是一对多
    3. 单向还是双向
    4. 性能
    5. 其他(安全性,代码可读性,实现复杂性)等等;

    源代码(通信方式1、2、3、4 Demo)

    public class MainActivity extends Activity implements View.OnClickListener, OnProgressListener, Handler.Callback{
    
    private DownloadService mDownloadService;
    private ProgressBar mProgressBar;
    
    private LocalBroadcastManager mLocalBroadcastManager;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        mProgressBar = (ProgressBar)findViewById(R.id.progressBar);
        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
    
        Intent intent = new Intent("com.example.downloadservice");
        bindService(intent, serviceConnection, BIND_AUTO_CREATE);
    
        mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
    
        EventBus.getDefault().register(this);
    }
    
    @Override
    protected void onResume() {
        super.onResume();
    
        mLocalBroadcastManager.registerReceiver(mBroadcastReceiver, new IntentFilter("from_downloadService"));
    }
    
    @Override
    protected void onDestroy() {
        unbindService(serviceConnection);
        mLocalBroadcastManager.unregisterReceiver(mBroadcastReceiver);
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }
    
    /**
     * 通信方式四:第三方开源组件eventbus
     * @param progressEvent
     */
    public void onEvent(ProgressEvent progressEvent) {
        mProgressBar.setProgress(progressEvent.getProgress());
    }
    
    /**
     * 通信方式一
     * @param progress
     */
    @Override
    public void OnProgress(int progress) {
        mProgressBar.setProgress(progress);
    }
    
    
    /**
     * 通信方式二
     * @param message
     */
    @Override
    public boolean handleMessage(Message message) {
        mProgressBar.setProgress(message.what);
        return false;
    }
    
    @Override
    public void onClick(View view) {
        int id = view.getId();
        switch (id) {
            case R.id.button1:
                mDownloadService.startDownload();
                break;
            case R.id.button2:
                break;
            default:
                break;
        }
    }
    
    ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mDownloadService = ((DownloadService.MsgBinder) iBinder).getService();
    
            /**
             * 通信方式一
             */
            /*if (mDownloadService != null) {
                mDownloadService.setOnProgressListener(MainActivity.this);
            }*/
    
            /**
             * 通信方式二
             * //TODO:考虑内存泄露
             */
            /*if (mDownloadService != null) {
                mDownloadService.setHandler(new Handler(MainActivity.this));
            }*/
        }
    
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }
    };
    
    /**
     * 通信方式三
     */
    BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            mProgressBar.setProgress(intent.getIntExtra("KEY_PROGRESS", -1));
        }
    };
    }
    

    =================================

    public class DownloadService extends Service {
    
    public final static int MAX_PROGRESS = 100;
    
    private int mProgress = 0;
    
    private OnProgressListener mOnProgressListener;
    
    private Handler mHandler;
    
    public DownloadService() {
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        return new MsgBinder();
    }
    
    /**
     * 通信方式一:通过回调的方式
     * @param onProgressListener
     */
    public void setOnProgressListener(OnProgressListener onProgressListener) {
        this.mOnProgressListener = onProgressListener;
    }
    
    /**
     * 通信方式二:通过持有Activity handler的方式
     * @param handler
     */
    public void setHandler(Handler handler) {
        this.mHandler = handler;
    }
    
    /**
     * //TODO:考虑并发性
     */
    public void startDownload() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (mProgress < MAX_PROGRESS) {
                    mProgress += 5;
    
                    /**
                     * 通信方式一
                     */
                    /*if (mOnProgressListener != null) {
                        mOnProgressListener.OnProgress(mProgress);
                    }*/
    
                    /**
                     * 通信方式二
                     */
                    /*if (mHandler != null) {
                        Message message = new Message();
                        message.what = mProgress;
                        mHandler.sendMessage(message);
                    }*/
    
    
                    /**
                     * 通信方式三
                     */
                    /*Intent intent = new Intent("from_downloadService");
                    intent.putExtra("KEY_PROGRESS", mProgress);
                    LocalBroadcastManager.getInstance(DownloadService.this).sendBroadcast(intent);*/
    
                    EventBus.getDefault().post(new ProgressEvent(mProgress));
    
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
    
    public class MsgBinder extends Binder {
    
        public DownloadService getService() {
            return DownloadService.this;
        }
    }
    }
    

    ===========================

    public interface OnProgressListener {
        void OnProgress(int progress);
    }
    

    ===========================

    public class ProgressEvent {
    public ProgressEvent(int mProgress) {
        this.mProgress = mProgress;
    }
    
    public int getProgress() {
        return mProgress;
    }
    
    public void setProgress(int mProgress) {
        this.mProgress = mProgress;
    }
    
    private int mProgress = 0;
    
    }
    

    参考

    [相关讨论]
    http://stackoverflow.com/questions/2463175/how-to-have-android-service-communicate-with-activity
    [相关讨论]
    http://stackoverflow.com/questions/20594936/communication-between-activity-and-service
    [LocalBroadcastManager官方参考]
    http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html
    [EventBus源码详解]
    https://github.com/android-cn/android-open-project-analysis/tree/master/tool-lib/event-bus/event-bus
    [EventBus 与otto应用和性能对比]
    http://timnew.me/blog/2014/09/14/otto-and-android-annotations-compatibility-issue-analysis/
    [EventBus 与otto源码实现对比]
    http://frodoking.github.io/2015/03/30/android-eventbus-otto-analysis/
    [其他]
    1.http://developer.samsung.com/technical-doc/view.do;jsessionid=vF09VyrXngrTLTX9f2gfn2zvP2GjTSqs1T91GWF31PNhHvlBc2gv!-1892717541?v=T000000087
    2.http://developer.android.com/reference/android/app/Service.html#RemoteMessengerServiceSample
    3.http://developer.android.com/guide/components/bound-services.html
    4.http://www.jikexueyuan.com/blog/308.html
    5.http://blog.philippheckel.com/2012/06/10/android-example-communication-between-activity-and-service-using-messaging/
    6.http://blog.csdn.net/xiaanming/article/details/9750689
    7.https://androidexperinz.wordpress.com/2012/02/21/communication-between-service-and-activity-part-2/

    相关文章

      网友评论

      • pgydbh:还有共享变量。算吗。?

      本文标题:Activity 与 Service 通信方式 总结

      本文链接:https://www.haomeiwen.com/subject/exrpqttx.html