Android后台进程与前台线程间的区别使用


博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved !


很早就翻译过Android API的一篇文章Android高级开发第四讲--API之Service,今天主要讲些实战的东西

比如Service的启动方式有两种,首先在AndroidManifest.xml中配置Service,然后通过bindService和startService来启动,

不同点在于:

执行方式:前者启动时执行onCreate-->onBind方法而且只执行一次;后者执行onCreate-->onStartCommand方法,onStartCommand方法却可以执行多次

通信方式:前者只能通过onBind传递一次值,然后拿到一个Bind类的引用来全传值

ForeService

	public int last(int index) {
		if (index == 0) {
			index = 4;
		} else {
			index -= 1;
		}
		sImageId = index % 5;
		return sImageId;
	}

	public class MyBinder extends Binder {
		public ForeService getService() {
			return ForeService.this;
		}
	}

调用类

		foreService = new Intent(this, ForeService.class);
		// 创建连接
		foreConn = new ServiceConnection() {

			@Override
			public void onServiceDisconnected(ComponentName name) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onServiceConnected(ComponentName name, IBinder service) {
				// TODO Auto-generated method stub
				myBinder = (MyBinder) service;
				transPortFore();
			}
		};
后者可以每次都可以通过onStartCommand方法里的intent对象传值,也可以通过上述方法传值。

以上是启动方式。当然不可能就讲这么一点知识,接下来的东西比较重要。

由于Android是根据进程来分配内存的,而我们的App运行在一块虚拟机上,也就是一个主进程;那么如果执行逻辑比较复杂,即使再多的线程(而且有限制),方法来了,给主进程开一个子进程,用什么来开呢?对,就是Service!因为今天只讲它。

首先在AndroidManifest.xml(如果一直读我博客,请记得以后它称为主配置文件),先看它,注册Service

		<service android:name="com.liuxian13183.service.BkService" android:process=".core" />
		<service android:name="com.liuxian13183.service.ForeService" />
我们可以看到命名为BkService的类,比下面ForeService多一个参数android:process,对就是这个参数,如果你不设就默认跟主进程同一个进程,如果设了不论点.还是冒号:,都代表新启动一个进程,而子进程跟主进程之间只能通过AIDL来通信。

其次,定义一个AIDL文件,返回值可以使用基础数据类型+List和Map,主要用来传值沟通

例:

package com.liuxian13183.service;
interface INext{
 int next(int index);
}


最后定义Service,在前端调用

Service定义:

public class BkService extends Service {
	private int sImageId = 0;

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		sImageId = intent.getIntExtra("key", 0);
		return new Next();
	}

	public class Next extends INext.Stub {
		@Override
		public int next(int index) throws RemoteException {
			// TODO Auto-generated method stub
			index += 1;
			sImageId = index % 5;
			return sImageId;
		}

	}
}
前端调用

		backService = new Intent(this, BkService.class);
		backConn = new ServiceConnection() {

			@Override
			public void onServiceDisconnected(ComponentName name) {
				// TODO Auto-generated method stub
				Log.i("com.liuxian13183.service", "");
			}

			@Override
			public void onServiceConnected(ComponentName name, IBinder service) {
				// TODO Auto-generated method stub
				iNext = INext.Stub.asInterface(service);
				transPortBack();
			}
		};

		if (iNext != null) {
					transPortBack();
				} else {// getConnection
					backService.putExtra("key", sImageId);
					startService(backService);
					bindService(backService, backConn, BIND_AUTO_CREATE);// 回调
				}

	private void transPortBack() {
		try {
			sImageId = iNext.next(sImageId);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		showAlbum();
	}

	private void showAlbum() {
		InputStream rawImageStream = getResources().openRawResource(sImageArray[sImageId]);
		byte[] data = WebpUtils.streamToBytes(rawImageStream);
		final Bitmap webpBitmap = WebpUtils.webpToBitmap(data);
		imageView.setImageBitmap(webpBitmap);
	}

效果如下:

Android后台进程与前台线程间的区别使用

这你最想要的源码!Android Service和webp讲解源码