Service和Activity通讯的3种常用方式示例

一般的Android业务开发中,Service的使用十分常见。稍微复杂点的业务逻辑,都需要Serivice在执行某些耗时操作后通知Activity。总结常见的三种方法。

        分别是:(1)binder持有Activity的Handler对象,或者持有一个Activity的callbackInterface.

        (2)AIDL实现,完美支持IPC。

          (3)startService+broadcastReceiver实现。

          另外还有几种不推荐的方式,都有很高的局限性。比如Service执行后的结果持久化,通过startActivity在目标Activity中的OnNewIntent()处理(需要Activity是单例的)。

         (1)Binder持有Activity的Handler,这里推荐Handler弱引用Activity实现。

           关键代码如下:           

public class WeakReferenceHandlerActivity extends Activity {
	private MyHandler mHandler;
	public static int FLAG = 10;
	public ProgressBar progressBar;
	private Button bindButton;
	private Button nextButton;
	private UseHandlerService.MyBinder myBinder;  
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.handler_layout);
		progressBar = (ProgressBar)this.findViewById(R.id.progress);
		bindButton = (Button)this.findViewById(R.id.bind);
		nextButton = (Button)this.findViewById(R.id.next);
		mHandler = new MyHandler(this);
		
		bindButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				bindService();
				Log.d("","startDownLoad() --> click");
			}
		});
		nextButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				startActivity(new Intent(WeakReferenceHandlerActivity.this,AndroidAidlActivity.class));
			}
		});
	}

	
	  
    private ServiceConnection connection = new ServiceConnection() {  
  
        @Override  
        public void onServiceDisconnected(ComponentName name) {  
        	
        }  
  
        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) { 
        	Log.d("","startDownLoad() --> onbind");
            myBinder = (UseHandlerService.MyBinder) service;  
            myBinder.setCallBackHandler(mHandler);
            myBinder.startDownLoad();
            
        }  
    };  
	
    @Override
	protected void onResume() {
    	
		super.onResume();
	}
    
    @Override
	protected void onPause() {
    	unBindService();
		super.onPause();
	}
    
    public void bindService(){
    	Intent bindIntent = new Intent(this, UseHandlerService.class);  
        bindService(bindIntent, connection, BIND_AUTO_CREATE);  
    }
    
    public void unBindService(){
    	unbindService(connection);
    }
    
	@Override
	protected void onDestroy() {
		// Remove all Runnable and Message.
		mHandler.removeCallbacksAndMessages(null);

		super.onDestroy();
	}

	public MyHandler getHandler(){
		return mHandler;
	}
	
	public class MyHandler extends Handler {
		// WeakReference to the outer class's instance.
		private WeakReference mOuter;

		public MyHandler(WeakReferenceHandlerActivity activity) {
			mOuter = new WeakReference(activity);
		}

		@Override
		public void handleMessage(Message msg) {
			WeakReferenceHandlerActivity outer = mOuter.get();
			if (outer != null) {
				// Do something with outer as your wish.
				if(!outer.isFinishing()){
					int progress = msg.what;
					progressBar.setProgress(progress);
				}
			}
		}
	}
}

public class UseHandlerService extends Service{
	/**
	 * 进度条的最大值
	 */
	public static final int MAX_PROGRESS = 100; 
	/**
	 * 进度条的进度值
	 */
	private int progress = 0;
	/**
	 * 更新进度的回调接口
	 */
	private MyHandler myHandler;
	private MyBinder mBinder = new MyBinder();  
	private String TAG = "UseHandlerService";
	/**
	 * 注册回调接口的方法,供外部调用
	 * @param onProgressListener
	 */
	public void setHandler(MyHandler handler) {
		myHandler = handler;
	}
	/**
	 * 增加get()方法,供Activity调用
	 * @return 下载进度
	 */
	public int getProgress() {
		return progress;
	}
	@Override  
    public void onCreate() {  
        super.onCreate();  
        Log.d(TAG, "onCreate() executed");  
    }  
  
    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        Log.d(TAG, "onStartCommand() executed");  
        return super.onStartCommand(intent, flags, startId);  
    }  
  
    @Override  
    public void onDestroy() {  
        super.onDestroy();  
        Log.d(TAG, "onDestroy() executed");  
    }  

	/**
	 * 返回一个Binder对象
	 */
	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}
	
	public class MyBinder extends Binder{
		/**
		 * 获取当前Service的实例
		 * @return
		 */
		public UseHandlerService getService(){
			return UseHandlerService.this;
		}
		
		public void setCallBackHandler(MyHandler handler){
			myHandler = handler;
		}
		
		public void startDownLoad(){
			Log.d("","startDownLoad() inBinder-->");
			new Thread(new Runnable() {
				public void run() {
					while(progress < MAX_PROGRESS){
						progress += 5;
						Log.d("","startDownLoad() run-->");
						//进度发生变化通知调用方
						if(myHandler != null){
							myHandler.sendEmptyMessage(progress);
						}
						try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}).start();
		}
	}
}
弱引用的实现,是出于防止Service不销毁,一直导致目标Activity也不能会回收的考虑。



(2)AIDL实现,同样还是进度条的UI更新。

public class AndroidAidlActivity extends Activity {
    /** Called when the activity is first created. */
	public static final int MAX_PROGRESS = 100; 
	/**
	 * 进度条的进度值
	 */
	private int progress = 0;
	public ProgressBar progressBar;
	private Button bindButton;

	private MyAIDLService mService;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.handler_layout);
        
        progressBar = (ProgressBar)this.findViewById(R.id.progress);
        bindButton = (Button)this.findViewById(R.id.bind);
		bindButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				bindService();
				Log.d("","startDownLoad() --> click");
			}
		});
		this.findViewById(R.id.next).setVisibility(View.GONE);
    }
    
    private ICallBack.Stub mCallback = new ICallBack.Stub() {
    	 
         @Override
         public void showResult(final int result) {
             Log.d("", "showresult -->" + result);
             progressBar.setProgress(result);
         }
    };
    
    private ServiceConnection connection = new ServiceConnection() {  
        @Override  
        public void onServiceDisconnected(ComponentName name) {  
        	mService = null;
        }  
        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) { 
        	Log.d("","startDownLoad() --> onbind");
        	mService = MyAIDLService.Stub.asInterface(service);
        	try {
        	    mService.registerCallback(mCallback);
        	    mService.startDownload();
        	} catch (RemoteException e) {
        	    Log.e("", "", e);
        	}
            
        }  
    };  
	
    @Override
	protected void onResume() {
		super.onResume();
	}
    
    @Override
	protected void onPause() {
    	unBindService();
		super.onPause();
	}
    
    public void bindService(){
    	Intent bindIntent = new Intent(this, AidlService.class);  
        bindService(bindIntent, connection, BIND_AUTO_CREATE);  
    }
    
    public void unBindService(){
    	unbindService(connection);
    }
    
	@Override
	protected void onDestroy() {
		// Remove all Runnable and Message.
		super.onDestroy();
	}
	

}
public class AidlService extends Service {

	private RemoteCallbackList mCallbacks = new RemoteCallbackList();
	
		MyAIDLService.Stub mBinder = new Stub() {

			@Override
			public void registerCallback(ICallBack cb) throws RemoteException {
				if(cb != null) {
                    mCallbacks.register(cb);
				}
			}
			@Override
			public void unregisterCallback(ICallBack cb) throws RemoteException {
				if(cb != null) {
                    mCallbacks.unregister(cb);
				}
			}

			@Override
			public void startDownload() throws RemoteException {
				Log.d("","startDownLoad() inBinder-->");
				new Thread(new Runnable() {

					public void run() {
						while(progress < MAX_PROGRESS){
							progress += 5;
							Log.d("","startDownLoad() run-->");
							//进度发生变化通知调用方
							if(mHandler != null){
								//TODO
								mHandler.sendEmptyMessage(progress);
							}
							
							try {
								Thread.sleep(1000);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
						}
						
					}
				}).start();
			}
		};
		/**
		 * 进度条的最大值
		 */
		public static final int MAX_PROGRESS = 100; 
		/**
		 * 进度条的进度值
		 */
		private int progress = 0;
		/**
		 * 更新进度的回调接口
		 */
		private String TAG = "UseHandlerService";
		/**
		 * 增加get()方法,供Activity调用
		 * @return 下载进度
		 */
		public int getProgress() {
			return progress;
		}

		@Override  
	    public void onCreate() {  
	        super.onCreate();  
	        //mHandler.sendEmptyMessageDelayed(0, 1000);
	        Log.d(TAG, "onCreate() executed");  
	    }  
		private void callBack(Message msg) {
			int N = mCallbacks.beginBroadcast();
			try {
			    for (int i = 0; i < N; i++) {
			    	Log.d("","mCallbacks -->progress"+msg.what);
			        mCallbacks.getBroadcastItem(i).showResult(msg.what);
			    }
			} catch (RemoteException e) {
			      Log.e(TAG, "", e);
			}
			mCallbacks.finishBroadcast();
		}
			
		private Handler mHandler = new Handler() {
			 
			      @Override
			      public void handleMessage(Message msg) {
			           callBack(msg);
			           super.handleMessage(msg);
			      }
			};
	    @Override  
	    public int onStartCommand(Intent intent, int flags, int startId) {  
	        Log.d(TAG, "onStartCommand() executed");  
	        return super.onStartCommand(intent, flags, startId);  
	    }  
	  
	    @Override  
	    public void onDestroy() {  
	        super.onDestroy();  
	        Log.d(TAG, "onDestroy() executed");  
	    }  
		/**
		 * 返回一个Binder对象
		 */
		@Override
		public IBinder onBind(Intent intent) {
			return mBinder;
		}
		

	}
还有两个AIDL文件
package com.banking.hello;

interface ICallBack {
    void showResult(int result);
} 

package com.banking.hello;
import com.banking.hello.ICallBack;
interface MyAIDLService {
	void registerCallback(ICallBack cb);
    void unregisterCallback(ICallBack cb);
    void startDownload();
}
这种方式,无论Service是否是remote,都可以实现高效率通讯。

(3)第三种通过Receiver非常简单,就不上代码了。
sendBroadCast,然后在Activity中注册一个相对应的内部receiver接受就可以了.

查看工程

 
  
 
  
 
  
 
  
 
 

你可能感兴趣的:(android,android,AIDL,Handler,bindService)