android 浅谈service

刚开始看Android,对service理解有错的地方,请大家猛评论。。。

service android应用程序中事务处理的地方。

有两种service:

第一种:用startService()启动的service

第二种:用bindService绑定的service

 

第一种:继承Service类,并需要重写onBind(),它的生命周期,onCreate()-->onStartCommand()-->onDestroy()

在onCreate()中可以初始化一些值(根据实际情况而定)

onStartCommand()中用来真正的处理一些事务逻辑

onDestroy() 用来处理Service(服务)关闭时的一些东西,如:关闭一些Service运行时候的所占用的一些资源

这个Service用stopService()来进行关闭

可以好多组件来启动该Service,可是只有一个Service运行。当关闭activity时,该服务继续运行,直到调用stopService()服务才终止。


MainAcitivity.java

package com.jiajai.exampleservicetest;

import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.os.Build;

public class MainActivity extends ActionBarActivity {
	
	private Button button1;
	private Button button2;
	
	private OnClickListener listener = new OnClickListener(){
		public void onClick(View v){
			Intent intent = new Intent(MainActivity.this, ExampleService.class);
			switch(v.getId()){
			case R.id.button1:
				startService(intent);
				break;
			case R.id.button2:
				stopService(intent);
				break;
			}
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.myactivity);
		button1 = (Button)findViewById(R.id.button1);
		button2 = (Button)findViewById(R.id.button2);
		
		button1.setOnClickListener(listener);
		button2.setOnClickListener(listener);
		// if (savedInstanceState == null) {
		// getSupportFragmentManager().beginTransaction()
		// .add(R.id.container, new PlaceholderFragment()).commit();
		// }
	}

	@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;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * A placeholder fragment containing a simple view.
	 */
	public static class PlaceholderFragment extends Fragment {

		public PlaceholderFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			View rootView = inflater.inflate(R.layout.fragment_main, container,
					false);
			return rootView;
		}
	}

}

ExampleService.java

package com.jiajai.exampleservicetest;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class ExampleService extends Service {
	
	private static final String TAG = "ExampleService";
	
	
	@Override
	public void onCreate() {
		
		Log.i(TAG, "ExampleService->onCreate");
		super.onCreate();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i(TAG, "ExampleService->onStartCommand");
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		Log.i(TAG, "ExampleService->onDestroy");
		super.onDestroy();
	}

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

}


第二种:继承Service类,需要在其内部写一个继承Binder的内部类且写出该内部类的实例, 并在onBind()返回该内部类的实例。

用bindService()来绑定Service,unbindService()来解除绑定

生命周期:onCreate()-->onBind()-->onUnbind-->onDestroy()

 bindService(intent, conn, BIND_AUTO_CREATE)

conn是ServiceConnection的实例

且通过ServiceConnection中onServiceConnected()方法来与绑定的Service进行联系,并调用Service中我们实际用到的一些事务处理的方法。。。


BinderAcitivity.java

package com.jiajai.exampleservicetest;

import com.jiajai.exampleservicetest.BinderService.MyBinder;

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.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class BinderActivity extends ActionBarActivity {
	
	private Button button1;
	private Button button2;
	
	private Boolean isConnected = false;
	
	private OnClickListener listener = new OnClickListener(){
		public void onClick(View v){
			switch(v.getId()){
			case R.id.button1:
				bindService();
				break;
			case R.id.button2:
				unBind();
				break;
			default:
				break;
			}
		}
	};
	
	public void bindService(){
		Intent intent = new Intent(BinderActivity.this, BinderService.class);
		bindService(intent, conn, Context.BIND_AUTO_CREATE);
	}
	
	public void unBind(){
		
		if(isConnected){
			unbindService(conn);
		}
		System.out.println("unBind");
		
	}
	
	private ServiceConnection conn = new ServiceConnection(){
		public void onServiceConnected(ComponentName name, IBinder service) {
			MyBinder myBinder = (MyBinder)service;
			BinderService binderService = myBinder.gerService();
			binderService.Method();
			isConnected = true;
		}
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			isConnected = false;
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.binder);
		button1 = (Button)findViewById(R.id.button1);
		button2 = (Button)findViewById(R.id.button2);
		
		button1.setOnClickListener(listener);
		button2.setOnClickListener(listener);
	}

}

BinderService.java

package com.jiajai.exampleservicetest;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class BinderService extends Service {
	private static final String TAG = "BinderService";
	
	private MyBinder myBinder = new MyBinder();
	
	public class MyBinder extends Binder{
		
		public BinderService gerService(){
			return BinderService.this;
		}
	}
	@Override
	public IBinder onBind(Intent intent) {
		return myBinder;
	}
	
	public void Method(){
		Log.i(TAG, "BinderService->method");
	}
	
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		System.out.println("BinderService->onDestroy");
	}

}


补:

1:onStartCommand()返回值

onStartCommand()方法必须返回一个整数,这个整数是一个描述了在系统的杀死事件中,系统应该如何继续这个服务的值(虽然你能够修改这个值,但是IntentService处理还是为你提供了默认实现)。从onStartCommand()方法中返回的值必须是以下常量:

 

START_NOT_STICKY

如果系统在onStartCommand()方法返回之后杀死这个服务,那么直到接受到新的Intent对象,这个服务才会被重新创建。这是最安全的选项,用来避免在不需要的时候运行你的服务。

 

START_STICKY

如果系统在onStartCommand()返回后杀死了这个服务,系统就会重新创建这个服务并且调用onStartCommand()方法,但是它不会重新传递最后的Intent对象,系统会用一个null的Intent对象来调用onStartCommand()方法,在这个情况下,除非有一些被发送的Intent对象在等待启动服务。这适用于不执行命令的媒体播放器(或类似的服务),它只是无限期的运行着并等待工作的到来。

 

START_REDELIVER_INTENT

如果系统在onStartCommand()方法返回后,系统就会重新创建了这个服务,并且用发送给这个服务的最后的Intent对象调用了onStartCommand()方法。任意等待中的Intent对象会依次被发送。这适用于那些应该立即恢复正在执行的工作的服务,如下载文件。

2:绑定服务为什么需要Binder内部类

Android 实现绑定服务,是通过onBind()方法实现的,而它返回的是IBinder对象,所以需要继承Binder的内部类。。。相当于把Service封装成Binder对象进行传递。。。

3:Service多线程

如果不需要同时处理多个线程,可以用IntentService来处理多线程

如果需要同时处理多个线程,则需要继承Service

类IntentService可以完成以下工作:

Ø  创建一个工作线程来处理所有发送到onStartCommand()的请求(Intent),从而应用的主线程分开

Ø  创建一个工作队列来逐个处理每个请求,从而无需考虑多线程编程。

Ø  在处理完所有请求后终止Service的运行,你无需调用stopService()来终止Service

Ø  提供onBind()的缺省实现,返回null

Ø  提供onStartCommand()的缺省实现,将接受到的Intent发送到工作队列中,然后调用你的onHandleIntent()实现

所以,只需要提供onHandleIntent()来处理发过来的Intent当然你可能还需要实现Service的一个简单的构造函数。。。


ExampleIntentActivity.java

package com.jiajai.exampleservicetest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ExampleIntentActivity extends ActionBarActivity {
	
	private Button button1;
	private Button button2;
	
	private Intent intent;
	
	private OnClickListener listener = new OnClickListener(){
		public void onClick(View v){
			switch(v.getId()){
			case R.id.button1:
				intent = new Intent(ExampleIntentActivity.this, MyService.class);
				System.out.println("主线程id: " + Thread.currentThread().getId());
				startService(intent);
				break;
			case R.id.button2:
				intent = new Intent(ExampleIntentActivity.this, MyIntentService.class);
				System.out.println("主线程id: " + Thread.currentThread().getId());
				startService(intent);
				break;
			default:
				break;
			}
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.intent);
		button1 = (Button)findViewById(R.id.button1);
		button2 = (Button)findViewById(R.id.button2);
		
		button1.setOnClickListener(listener);
		button2.setOnClickListener(listener);
	}

}

MyService.java

package com.jiajai.exampleservicetest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyService extends Service {
	
	@Override
	public void onCreate() {
		super.onCreate();
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		
		new MyThread().start();
		return START_STICKY;
	}
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	private class MyThread extends Thread{
		@Override
		public void run() {
			try{
				System.out.println("MyService的线程id: " + Thread.currentThread().getId());
				System.out.println("文件下载。。。");
				Thread.sleep(2000);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}

}

MyIntentService.java

package com.jiajai.exampleservicetest;

import android.app.IntentService;
import android.content.Intent;

public class MyIntentService extends IntentService {
	
	public MyIntentService() {
		
		super("MyIntentService");
	}
	@Override
	protected void onHandleIntent(Intent intent) {
		
		System.out.println("MyService的线程id: " + Thread.currentThread().getId());
		System.out.println("文件下载。。。");
		try{
			Thread.sleep(2000);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

}


4:bindService中的参数

  • 第一个bindService()的参数是一个明确指定了要绑定的service的Intent.

  • 第二个参数是ServiceConnection对象.

  • 第三个参数是一个标志,它表明绑定中的操作.它一般应是BIND_AUTO_CREATE,这样就会在service不存在时创建一个.其它可选的值是BIND_DEBUG_UNBIND和BIND_NOT_FOREGROUND,不想指定时设为0即可.。




你可能感兴趣的:(android 浅谈service)