ActivityとServiceの通信方式まとめ

7542 ワード

つうしんモード


1.binder+コールバック(listener)


主な考え方:Activityはインスタンスをサービスに転送し、コールバックを利用してUIを更新する.

2. binder + Handler


主な考え方:サービスはActivityのHandlerオブジェクトを持ち、サービスはこのHandler send messageに向かうことで通信の目的を達成する.

3.ブロードキャスト(推奨LocalBroadcastManager)


主な考え方:システムのLocalBroadcastManager、Service send message、Activity receive messageを利用する;

4.オープンソースコンポーネント(EventBus,otto)


主な考え方:反射や注釈で登録クラスの登録を実現し、現在のレジストリを巡り、keyでクエリーを行い、dispatchし、対応するイベント処理方法を呼び出す.(オープンソースフレームワークの実装によって異なります)

5. AIDL


主な考え方://ODO

まとめ


現在、Androidコンポーネント間の主流の通信方式は、上記の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/