Android Service는 Messenger를 사용하여 프로세스 간 통신 프레임워크

5699 단어 aidlmessenger
전편에서 Binder 메커니즘의 통신 구조를 말했듯이 Messenger의 밑바닥은 AIDL에서 이루어진다고 말했기 때문에 크로스 프로세스 통신에서 Messenger는 비교적 고급스러운 구조로 한 app 개발자에게 중요한 것은 말하지 않아도 알 수 있다.
서비스 사이드 모델
public class BackgroundService extends Service
{

       private Messenger mMessenger = null;//    
       
       private Messenger replyMessenger = null //    
        @Override
	public IBinder onBind(Intent intent) 
	{
	        if(mMessenger==null)
	        {
	           mMessenger = new Messenger(new ServerHandler());
	        }
		return mMessenger.getBinder();
	}

	 @Override
	public boolean onUnbind(Intent intent) 
	{
		return super.onUnbind(intent);
	}
	
    //  , ServerHandler   ,       
    public static class ServerHandler extends Handler
    {
        	@Override
		public void handleMessage(Message msg) 
		{
			if (msg.what == 0x000001) 
			{
				try 
				{
				    replyMessenger = msg.replyTo;
				    replyMessenger.send(Message.obtain(null,0x000001, HttpStatus.SC_OK, 0));
				    LogUtils.e("[    ]=>    ,     <MSGID[FlightID:"+msg.obj+",arg1:"+msg.arg1+"]>");
				}
				 catch (RemoteException e)
				{
					e.printStackTrace();
				}
			}
			else if(msg.what == 0x000002)
			{
				try 
				{
				    replyMessenger = msg.replyTo;
				    replyMessenger .send(Message.obtain(null,0x000002,HttpStatus.SC_OKT, 0));
				    LogUtils.e("[    ]=>    ,     <MSGID[FlightID:"+msg.obj+",arg1:"+msg.arg1+"]>");
				}
				 catch (RemoteException e)
				{
				    e.printStackTrace();
				}
			}
		else
		{
			super.handleMessage(msg);
		}
	}    
    }
}

클라이언트 모델
public class MainActivity extends Activity
{

        private Activity activity = null;
        private final int RETRY_INTERVAL_TIME = 2 * 1000;

        private final Messenger clientMessenger= new Messenger(new ClientHandler());
        
        private Messenger replyMessenger = null;
        @Override
	protected void onCreate(Bundle savedInstanceState)
	 {
		super.onCreate(savedInstanceState);
		activity = this;
		
		startBackgroundService(this);
		//        ,                       
		bindgroundService(); 
	}

public static class ClientHandler extends Handler
{
       @Override
	    public void handleMessage(Message msg) 
	    {
	        if (msg.what == HttpStatus.SC_OK)
	         {
	        	//msg.arg1  remoteInt
	             Log.i("TAG", "       :"+msg.arg1);
	        } else {
	             super.handleMessage(msg);
	        }
	 }
}

/**    */
	private ServiceConnection  serviceConnection = new ServiceConnection() 
	{
		@Override
		public void onServiceDisconnected(ComponentName name)
		{
			replyMessenger = null;
			LogUtils.d("ServiceClient>>service onServiceDisconnected :    ");
		}
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) 
		{
			replyMessenger = new Messenger(service);
			LogUtils.d("ServiceClient>>service onServiceConnected :     ");
			if(replyMessenger !=null)
			{
				LogUtils.e("[    ]==>    ,    ,     !");

				Message msgTo =  Message.obtain(null,200);
				msgTo.obj = "[          ]";
				msgTo.arg1 = 1024;
				msgTo.replyTo = clientMessenger;
				try 
				{
					rccBackgroundService.send(msgTo);
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}
		}
	}; 

/**
 *       
 * @param context
  */
  private void startBackgroundService(Context context)
 {
	if(!isServiceRunning(BackgroundService.class.getName(),context))
	{
		Intent targetIntent = new Intent(context,RCCBackgroundService.class);
			//targetIntent.setAction(TARGET_SERVICE_ACTION);
		context.startService(targetIntent);
	}
}

/**
*       
*/
private void bindgroundService()
{
	if(rccBackgroundService==null && isServiceRunning(BackgroundService.class.getName()))
	{
		Log.e("[    ]","[    ]");
		activity.getWindow().getDecorView().postDelayed(new Runnable()
		{
			@Override
			public void run()
			{
				Intent intent = new Intent(activity, BackgroundService.class);
				intent.setAction(WifiNetworkChangedReceiver.TARGET_SERVICE_ACTION);
				activity.bindService(intent, serviceConnection, Service.BIND_AUTO_CREATE);
			}
		}, RETRY_INTERVAL_TIME);
	}else{
		activity.getWindow().getDecorView().postDelayed(new Runnable() {
			@Override
			public void run() {
				rccBackgroundService = null;
				bindgroundService();
			}
			}, RETRY_INTERVAL_TIME);
		}
	}
	
	
	/**
	 *   Service      
	 * @param serviceClassName
	 * @return
	 */
	public  boolean isServiceRunning(String serviceClassName)
	{ 
            final ActivityManager activityManager = (ActivityManager)activity.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); 
            final List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE); 
     
            for (RunningServiceInfo runningServiceInfo : services) 
            { 
                if (runningServiceInfo.service.getClassName().equals(serviceClassName))
                { 
                	LogUtils.e("-ServiceClient->      ,        ");
                    return true; 
                } 
            } 
            LogUtils.e("->ServiceClient->     ,          !");
            return false; 
     }
	
}

---------------------------------------------------------------------
의문에 대해 Messenger를 사용하는 것은 AIDL의 편리함이 없다. AIDL은 IPC 에이전트 방식이기 때문에 상황에 따라 결정해야 한다. 소형 프로젝트에 대해서는 IPC 에이전트를 사용할 필요가 없지만 큰 프로젝트에 대해서는 IPC 에이전트를 사용하는 것이 가장 좋다. 왜냐하면 IPC 에이전트는 인터페이스를 위한 서비스이기 때문이다.
참고: Messenger와 AIDL의 관계에서 그들은 모두 Parcelable를 사용하여 복잡한 유형의 데이터를 전달할 수 있으며 AIDL은 상대적으로 밑바닥이고 유연성이 좋다.

좋은 웹페이지 즐겨찾기