`
ivoter
  • 浏览: 90806 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

android系列学习【一】service和intentservice

 
阅读更多

每天进步一点,许多年后再回首就会发现现在的成就,是以前点滴努力的串联。

 

1.什么是service:

 

A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use. Each service class must have a corresponding <service> declaration in its package's AndroidManifest.xml. Services can be started withContext.startService() and Context.bindService().

 

service是一个应用程序组件,用来执行一个长时间运行的操作而不是与用户交互或提供其他应用程序使用的功能。每个service服务必须在AndroidManifest.xml文件中注册 <service> 。可以使用Context.startService() 

 Context.bindService()方法启动一个sevice。

 

注意:service不是一个单独的进程,也不是一个线程。即service域ui共享一个线程,如果在service中执行耗时操作会导致主线程阻塞。

 

2.什么是intentservice:

 

IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.

 

intentservice是一个service的子类,提供异步请求处理intent。可以使用startService(Intent)启动它;当intentservice启动后,会使用一个work线程异步处理intent,每次只能处理一个intent。

 

3.效果演示:

 

创建service

 

public class ServiceTest extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		System.out.println("=========service========="+Thread.currentThread().getId());
		try {
			//线程休眠10分钟
			Thread.sleep(100000);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return super.onStartCommand(intent, flags, startId);
	}

	
}

 创建intentservice

 

public class IntentServiceTest extends IntentService {

	public IntentServiceTest(String name) {
		super("test");
	}

	@Override
	protected void onHandleIntent(Intent intent) {
		System.out.println("=========intentservice========="+Thread.currentThread().getId());
		try {
			Thread.sleep(10000);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

 创建两个按钮分别启动service和intentservice

 

public class MainActivity extends Activity {

	private Button startservice=null;
	private Button startintentservice=null;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //打印当前线程id
        System.out.println("=========ui主线程========="+Thread.currentThread().getId());
        
        //实例化组件
        startservice=(Button) findViewById(R.id.startservice);
        startintentservice=(Button) findViewById(R.id.startintentservice);
        
        //绑定监听事件
        startservice.setOnClickListener(new MyOnclickListener());
        startintentservice.setOnClickListener(new MyOnclickListener());
    }

    private class MyOnclickListener implements OnClickListener{

		public void onClick(View v) {
			if(v==startservice){
				Intent service=new Intent();
				service.setClass(MainActivity.this, ServiceTest.class);
				startService(service);
			}else if(v==startintentservice){
				Intent service=new Intent();
				service.setClass(MainActivity.this, IntentServiceTest.class);
				startService(service);
			}
		}
    	
    }
首先启动service:线程被阻塞如图1:后台打印内容
11-19 01:53:08.300: INFO/System.out(226): =========ui主线程=========1
11-19 01:53:12.238: INFO/System.out(226): =========service=========1
   启动intentservice:线程不阻塞但,多次点击同一个线程一次只处理一个intent,当处理完成后才会从队列中取出下一个执行。

intentService代码解析:
public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }

    public IntentService(String name) {
        super();
        mName = name;
    }

    /**
     * Control redelivery of intents.  If called with true,
     * {@link #onStartCommand(Intent, int, int)} will return
     * {@link Service#START_REDELIVER_INTENT} instead of
     * {@link Service#START_NOT_STICKY}, so that if this service's process
     * is called while it is executing the Intent in
     * {@link #onHandleIntent(Intent)}, then when later restarted the same Intent
     * will be re-delivered to it, to retry its execution.
     */
    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }
    
    @Override
    public void onCreate() {
        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }
    
    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    /**
     * Invoked on the Handler thread with the {@link Intent} that is passed to {@link #onStart}.
     * Note that this will be invoked from a different thread than the one that handles the
     * {@link #onStart} call.
     */
    protected abstract void onHandleIntent(Intent intent);
}
 

比较:sevice处理不会自动开启线程,所以对于耗时操作例如mp3下载等需要开启新线程;intentservice会开启work线程处理,进行异步处理,但每次只有一个intent被处理。
  • 描述: 图1
  • 大小: 45.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics