zoukankan      html  css  js  c++  java
  • [Android学习笔记5]四大应用组件之一:Service 下

    绑定方式的Service使用

    在实现绑定服务时,最重要的是定义onBind()回调方法返回的接口,有三种方式:

    1. 继承Binder类

    2. 使用Messenger

    3. 使用AIDL

    这里对1,2方式进行分析。

    1.继承Binder类

    如果你的服务是你的应用程序的私有服务,并且跟客户端运行在同一个进程中,那么就应该通过继承Binder类来创建你的接口,并且佛从onBind()方法中返回这个接口的一个实例。客户端接收这个Binder对象,并且能够使用这个对象直接访问Binder类中实现的或Service中的公共方法。

    使用官方SDK文档中的例子:

    ServiceShow.java

    package com.luoye.servicelearn;
    
    import java.util.Random;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    
    
    public class ServiceShow extends Service{
    
    	private final IBinder binder = new LocalBinder();//创建Service的内部IBinder对象
    	
    	public class LocalBinder extends Binder
    	{
    		ServiceShow getService() //实现Binder自己的方法,这里返回Service对象的引用
    		{
    			return ServiceShow.this;
    		}
    	}
    	
    	public int getRandomNumber()
    	{
    		return (new Random()).nextInt(100);
    	}
    	
    	
    	@Override
    	public IBinder onBind(Intent intent) {
    		// TODO Auto-generated method stub
    		//返回一个IBinder对象,即Service的内部IBinder对象,作为ServiceConnection中onServiceConnected方法的IBinder传入
    		return binder;      
    	}
    
    }

    MainActivity.java

    package com.luoye.servicelearn;
    
    import com.luoye.servicelearn.ServiceShow.LocalBinder;
    
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Context;
    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.widget.Toast;
    
    public class MainActivity extends Activity {
    	
    	ServiceShow localService;
    	boolean bound = false;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    	}
    
    	@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 void buttonOnClickListener(View v)
    	{
    		switch(v.getId())
    		{
    			case R.id.start_service1:
    				Intent intent_start = new Intent(this, ServiceShow.class);
    				//绑定Service  第二个参数为ServiceConnection对象,由于bindService是异步的,
    				//bindService()方法立即返回并且不返回IBinder对象,所以需要在ServiceConnection的方法中去处理
    				//BIND_AUTO_CREATE表示if Service不存在,即onCreate()
    				bindService(intent_start, connection, Context.BIND_AUTO_CREATE); 
    				break;
    			case R.id.stop_service1:
    				if(bound)
    				{
    					unbindService(connection);
    					bound = false;
    				}//解绑Service
    				break;					
    			case R.id.show_random:
    				if(bound == true)
    				{
    					Toast.makeText(this, "number is :"+localService.getRandomNumber(), Toast.LENGTH_SHORT).show();
    				}
    				break;
    		}	
    	}
    	
    	private ServiceConnection connection = new ServiceConnection()
    	{
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    			// TODO Auto-generated method stub
    			LocalBinder binder = (LocalBinder)service; //得到service的IBinder对象
    			localService = binder.getService();//得到Service的引用,后续即可使用Service的方法
    			bound = true;
    		}
    
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    			// TODO Auto-generated method stub
    			bound = false;
    		}
    		
    	};
    
    }
    


     

    2. 使用Messenger

    如果需要服务跟远程进程通信,那么就可以使用Messenger对象来给服务提供接口。

    以下是信使(Messenger)对象的使用概要:

    1.  服务端实现的一个处理器(Handler接口),这个处理器针对每次来自客户端的调用接收一次回调;

    2.  这个处理器被用于创建一个信使对象(Messager)(这个信使对象要引用这个处理器);

    3.  信使对象创建一个创建一个服务端从onBind()方法中返回给客户端的IBinder对象;

    4.  客户端使用这个IBinder对象来实例化这个信使对象(信使引用了服务端的处理器),客户端使用这个信使给服务端发送Message对象;

    5.  服务端在它的处理器(Handler)的handleMessage()方法中依次接收每个Message对象

    在这种方法中,没有给客户端提供服务端的方法调用,相反,客户端会给发送服务端消息(Message)对象,服务端会在它的处理器中接受这些消息对象。

    代码:

    ServiceShow.java

    package com.luoye.servicelearn;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.os.Messenger;
    import android.widget.Toast;
    
    
    public class ServiceShow extends Service{
    
    	static final int MSG_CODE = 0x10;//message的消息类型定义
    	
    	class IncomingHandler extends Handler  //message处理器,应与信使绑定
    	{
    		public void handleMessage(Message msg)
    		{
    			switch(msg.what)
    			{
    				case  MSG_CODE:
    					Toast.makeText(ServiceShow.this, "Hello world", Toast.LENGTH_SHORT).show();
    					break;
    				default:
    					super.handleMessage(msg);
    			}
    		}
    	}
    	//创建一个信使,该信使使用Handler对象作为msg的处理器
    	final Messenger messenger = new Messenger(new IncomingHandler());
    	
    	
    	@Override
    	public IBinder onBind(Intent intent) {
    		// TODO Auto-generated method stub
    		Toast.makeText(ServiceShow.this, "Binding", Toast.LENGTH_SHORT).show();
    		return messenger.getBinder();//返回对应信使的Binder,返回给client使用
    	}
    
    
    
    }
    


    MainActivity.java

    package com.luoye.servicelearn;
    
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.os.Message;
    import android.os.Messenger;
    import android.view.Menu;
    import android.view.View;
    
    public class MainActivity extends Activity {
    	
    	Messenger messenger;
    	boolean bound = false;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    	}
    
    	@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 void buttonOnClickListener(View v)
    	{
    		switch(v.getId())
    		{
    			case R.id.start_service1:
    				Intent intent_start = new Intent(this, ServiceShow.class);
    				//绑定Service  第二个参数为ServiceConnection对象,由于bindService是异步的,
    				//bindService()方法立即返回并且不返回IBinder对象,所以需要在ServiceConnection的方法中去处理
    				//BIND_AUTO_CREATE表示if Service不存在,即onCreate()
    				bindService(intent_start, connection, Context.BIND_AUTO_CREATE); 
    				if(bound)
    				{
    					//产生message对象
    					Message msg = Message.obtain(null, ServiceShow.MSG_CODE, 0, 0);
    					try
    					{
    						//使用client端的信使发送message,该消息会通过Binder对应的信使递交到Service端的
    						//信使,并由该端信使的消息处理器Handler进行处理
    						messenger.send(msg);
    					}
    					catch (Exception e)
    					{
    						e.printStackTrace();
    					}
    				}
    				break;
    			case R.id.stop_service1:
    				if(bound)
    				{
    					unbindService(connection);//解绑Service
    					bound = false;
    				}
    				break;					
    		}	
    	}
    	
    	private ServiceConnection connection = new ServiceConnection()
    	{
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    			// TODO Auto-generated method stub
    			messenger = new Messenger(service); //利用Service返回的信使的对应的IBinder来创建client端的信使对象
    			bound = true;
    		}
    
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    			// TODO Auto-generated method stub
    			messenger = null;
    			bound = false;
    		}
    		
    	};
    
    }
    


     

  • 相关阅读:
    JSDOM优化
    Firebug Console 与命令行全集
    input输入框和 pure框架中的 box-sizing 值问题
    模块化网站注意事项
    COOKIE
    鼠标滚动
    拖拽的基本函数(已有限制范围和修复浏览器默认行为以及磁性吸附、碰撞检测、改变层大小、模拟滚动条)
    app_can 的AJax异步,两个解决方案
    基于jQuery的message插件实现右下角弹出消息框
    C#后台讲字符串转化为计算公式
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3202692.html
Copyright © 2011-2022 走看看