理解Android的本地Service和跨进程Service

本地Service的bindService的使用方法

1、建本地服务端
package com.tang.Javen;

import android.app.Service;

public class ProcessInService extends Service
{
	private String TAG = "ProcessInService";
	
	@Override
	public void onCreate()
	{
		// TODO Auto-generated method stub
		Log.d(TAG, "onCreate");
		super.onCreate();
	}

	@Override
	public void onDestroy()
	{
		// TODO Auto-generated method stub
		Log.d(TAG, "onDestroy");
		super.onDestroy();
	}

	@Override
	public void onStart(Intent intent, int startId)
	{
		// TODO Auto-generated method stub
		Log.d(TAG, "onStart");
		super.onStart(intent, startId);
	}

	@Override
	public boolean onUnbind(Intent intent)
	{
		// TODO Auto-generated method stub
		Log.d(TAG, "onUnbind");
		return super.onUnbind(intent);
	}

	@Override
	public IBinder onBind(Intent arg0)
	{
		// TODO Auto-generated method stub
		Log.d(TAG, "onBind");
		return new TestBinder();
	}
	class TestBinder extends Binder
	{
		public void printName(String name)
		{
			Log.d(TAG, "printName ="+name);
		}
	}
}
重点在onBind方法的返回值这里,当客户端通过bindService调用该Service时,会调用这个Service中的onBind函数,这里我们return new TestBinder();
然后自定义一个类TestBinder继承Binder,这样服务端就可以了。

2、在AndroidManifest.xml中声明这二个服务
   <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".ProcessInServiceActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="com.tang.Javen.ProcessInService">
            
        </service>
    </application>

3、构建客户端,新建一个ProcessInServiceActivity,在这个Activity中调用服务
package com.tang.Javen;

import android.app.Activity;

public class ProcessInServiceActivity extends Activity {
    /** Called when the activity is first created. */
	private Button startServiceBtn, stopServiceBtn;
	private ProcessInService.TestBinder iBinder;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        startServiceBtn = (Button)findViewById(R.id.onbind);
        stopServiceBtn = (Button)findViewById(R.id.unbind);
        
        
        startServiceBtn.setOnClickListener(new OnClickListener()
		{
			
			public void onClick(View v)
			{
				// TODO Auto-generated method stub
				Intent intent = new Intent(ProcessInServiceActivity.this, ProcessInService.class);
				bindService(intent, conn, ProcessInServiceActivity.this.BIND_AUTO_CREATE);
			}
		});
        
        stopServiceBtn.setOnClickListener(new OnClickListener()
		{
			
			public void onClick(View v)
			{
				// TODO Auto-generated method stub
				unbindService(conn);
			}
		});
        
        
    }
    
    private ServiceConnection conn = new ServiceConnection()
	{
		
		public void onServiceDisconnected(ComponentName name)
		{
			// TODO Auto-generated method stub
			
		}
		
		public void onServiceConnected(ComponentName name, IBinder service)
		{
			// TODO Auto-generated method stub
			iBinder = (ProcessInService.TestBinder)service;
			iBinder.printName(" Hello Javen.tang ");
		}
	};
}
在客户端重点在于new ServiceConnection(),然后当使用 bindService连接上了服务之后就会调用 onServiceConnected获取Service中onBind返回的IBinder。
点击绑定服务可以看到Hello Javen.tang这个打印说明服务启动成功。



使用AIDL跨进程访问服务

1、构建服务端,首先在src目录下新建一个com.tang.aidl的包,然后在该包中新建一个IPerson.aidl文件

package com.tang.aidl;

interface IPerson
{
	String printName(String name);
}
这样eclipse会根据这个aidl文件自动在gen目录下生成一个相同包名的IPerson.java文件

这样接口文件就有了,然后编写Service文件,新建一个AIDLService
package com.tang.Javen;

import android.app.Service;

public class AIDLService extends Service {
    /** Called when the activity is first created. */
	private String TAG = "AIDLService";
	IPerson.Stub stub = new IPerson.Stub()
	{
		
		public String printName(String name) throws RemoteException
		{
			// TODO Auto-generated method stub
			Log.d(TAG, "Hello" + name);
			return "Hello" + name;
		}
	};
	
	@Override
	public IBinder onBind(Intent arg0)
	{
		// TODO Auto-generated method stub
		return stub;
	}

	@Override
	public void onCreate()
	{
		// TODO Auto-generated method stub
		super.onCreate();
	}

	@Override
	public void onDestroy()
	{
		// TODO Auto-generated method stub
		super.onDestroy();
	}

	@Override
	public void onStart(Intent intent, int startId)
	{
		// TODO Auto-generated method stub
		super.onStart(intent, startId);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId)
	{
		// TODO Auto-generated method stub
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public boolean onUnbind(Intent intent)
	{
		// TODO Auto-generated method stub
		return super.onUnbind(intent);
	}
}
这里可以看到跟本地调用service的方法没有什么区别,只有在onBind的返回值这里是有不一样的,这里返回的是stub,而stub则是IPerson.Stub
	IPerson.Stub stub = new IPerson.Stub()
	{
		
		public String printName(String name) throws RemoteException
		{
			// TODO Auto-generated method stub
			Log.d(TAG, "Hello" + name);
			return "Hello" + name;
		}
	};
然后在AndroidManifest.xml中注册该服务
        <service android:name="com.tang.Javen.AIDLService">
            <intent-filter>
                <action android:name="android.intent.action.tang.AIDLService"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </service>
最后,这里写一个Activiy便于启动该service到虚拟机中去
package com.tang.Javen;

import android.app.Activity;

public class AIDLServiceActivity extends Activity
{

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}
	
}
这样服务端就可以了

2、把service中的aidl文件拷贝到客户端,这样服务端和客户端之间就有共用的接口了
package com.tang.client;

import com.tang.aidl.IPerson;

public class AIDLClientActivity extends Activity implements OnClickListener{
    /** Called when the activity is first created. */
	private Button onBindButton, printButton, unBindButton;
	private IPerson personProxy;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        onBindButton = (Button)findViewById(R.id.onbind);
        printButton = (Button)findViewById(R.id.print);
        unBindButton = (Button)findViewById(R.id.unbind);
        
        onBindButton.setOnClickListener(this);
        printButton.setOnClickListener(this);
        unBindButton.setOnClickListener(this);
    }
	public void onClick(View v)
	{
		// TODO Auto-generated method stub
		switch (v.getId())
		{
		case R.id.onbind:
			Intent intent = new Intent("android.intent.action.tang.AIDLService");
			bindService(intent, conn, AIDLClientActivity.this.BIND_AUTO_CREATE);
			break;
		case R.id.print:
			try
			{
				personProxy.printName("Tecon Javen.tang");
			} catch (RemoteException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			break;
		case R.id.unbind:
			unbindService(conn);
			break;

		default:
			break;
		}
	}
	
	private ServiceConnection conn = new ServiceConnection()
	{
		
		public void onServiceDisconnected(ComponentName name)
		{
			// TODO Auto-generated method stub
			
		}
		
		public void onServiceConnected(ComponentName name, IBinder service)
		{
			// TODO Auto-generated method stub
			personProxy = IPerson.Stub.asInterface(service);
		}
	};
}
这里跟本地服务的调用方法也基本类似,也是通过bindService来连接服务,不同的是在onServiceConnected中讲IBinder service通过IPerson.Stub.asInterface(service)将这个IBinder转化为IPerson。
然后通过personProxy这个IPerson调用service中的函数就可以了。
这样我们先启动AIDLService,然后在启动AIDLClient


点击onBind后再点击printName这可以看到HelloTecon Javen.tang, 这就说明服务调用成功了


记录下来,以便以后查看!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值