关于 android service 和 thread

本文深入解析 Android 中 Service 的工作原理及使用方式,对比 startService 和 bindService 的不同生命周期,并通过示例代码展示如何启动和绑定 Service。此外还讨论了 Service 与 Activity 之间的交互以及 Service 如何与其他组件协同工作。

在安卓系统中,service是运行在主线程中的,而thread是用来创建子线程的。二者毫无关系! thread的运行时独立于activity的,当一个activity被销毁时,如果你没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。当 Activity 被 finish 之后,你不再持有该 Thread 的引用。另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。 但是service却不同,当一个activity被销毁时,另外的activity还可以对service进行控制。因为任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例。因此可以把 Service 想象成一种消息服务,而你可以在任何有 Context 的地方调用 Context.startService、Context.stopService、 Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,当然这些都是 Thread 做不到的。

 

service

       Service的生命周期方法比Activity少一些,只有onCreate, onStart(onStartCommand), onDestroy

  我们有两种方式启动一个Service,他们对Service生命周期的影响是不一样的。

 

      1.通过startService启动

       Service会经历 onCreate --> onStart(onStartCommand)

  stopService的时候直接onDestroy

  如果是 调用者 直接退出而没有调用stopService的话,Service会一直在后台运行。

  下次调用者再起来仍然可以stopService。

     

      2.通过bindService启动

       Service只会运行onCreate, 这个时候 调用者和Service绑定在一起

  调用者退出了,Srevice就会调用onUnbind-->onDestroyed

  所谓绑定在一起就共存亡了。

     一个bindService启动的例子:

     ServiceDemo.java

   

public class ServiceDemo extends Activity {
	Button btnBind, btnUnBind, btnGetServiceStatus;
	BindService bindService;
	LocalService localService;
	private boolean isBind = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		btnBind = (Button) findViewById(R.id.btnBind);
		btnUnBind = (Button) findViewById(R.id.btnUnBind);
		btnGetServiceStatus = (Button) findViewById(R.id.btnGetServiceStatus);
		OnClickListener listener = new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				switch (v.getId()) {
				case R.id.btnBind:
					// Intent intent = new Intent();
					// // 隐式启动Service
					// intent.setAction("com.wang.servicedemo.BIND_SERVICE");
					// 显示启动Service
					Intent intent = new Intent(ServiceDemo.this,
							BindService.class);
					// 绑定指定的Service
					bindService(intent, serviceConnection, BIND_AUTO_CREATE);
					isBind = true;
					break;
				case R.id.btnUnBind:
					if (isBind) {
						// 解除绑定Service,一般要是没有主动去解绑的话,可以在onDestory方法中解绑
						unbindService(serviceConnection);
						isBind = false;
						bindService = null;
						Toast.makeText(ServiceDemo.this,
								"--Service is Unbind.--", Toast.LENGTH_LONG)
								.show();
					} else {
						Toast.makeText(ServiceDemo.this, "--你还未绑定Service--",
								Toast.LENGTH_LONG).show();
					}
					break;
				case R.id.btnGetServiceStatus:
					if (bindService == null) {
						Toast.makeText(ServiceDemo.this, "请先绑定Service",
								Toast.LENGTH_LONG).show();
					} else {
						Toast.makeText(
								ServiceDemo.this,
								"App name:" + bindService.getDemoName()
										+ "\n count:" + localService.getCount(),
								Toast.LENGTH_LONG).show();
						// localService.getService().MyMethod();
					}
					break;
				}
			}
		};
		btnBind.setOnClickListener(listener);
		btnGetServiceStatus.setOnClickListener(listener);
		btnUnBind.setOnClickListener(listener);
	}

	/**
	 * 定义一个ServiceConnection对象, 实例化ServiceConnection接口的实现类,
	 * 重写onServiceConnected()和onServiceDisconnected()方法
	 */
	private ServiceConnection serviceConnection = new ServiceConnection() {
		// 当Activity与Service通过非UnBind()方法断开连接的时候回调该方法
		@Override
		public void onServiceDisconnected(ComponentName name) {
			bindService = null;
			Toast.makeText(ServiceDemo.this, "--Service UnConnected.--",
					Toast.LENGTH_LONG).show();
		}

		// 当Activity与Service连接成功的时候回调该方法
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// 获取getService()方法返回的BindService对象
			localService = ((LocalService) service);
			bindService = localService.getService();
			bindService.MyMethod();
			Toast.makeText(ServiceDemo.this, "--Service Connected.--",
					Toast.LENGTH_LONG).show();
			System.out.println("--Service Connected.--");
		}
	};
}

 

        BindService.java

public class BindService extends Service {
	private int count = 0;
	private boolean isQuit = false;
	// 定义getService方法返回的对象
	public LocalService localService = new LocalService();

	/*
	 * 创建Binder子类,Binder实现了IBinder接口, 这是一个内部类
	 */
	public class LocalService extends Binder {
		public int getCount() {
			return count;
		}

		public BindService getService() {
			return BindService.this;
		}
	}

	/*
	 * Service子类必须实现的方法,绑定该Service时回调的方法; onbind方法只被调用一次,在第一个client或调用者
	 * 绑定至其的时候被调用。 返回的是Binder对象。 然后其他组件可以通过这个Binder 对象与该service 进行通讯。
	 */
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return localService;
	}

	/*
	 * (non-Javadoc) 此方法只执行一次,当service再次被调用时,会执行onStartCommand方法
	 * 
	 * @see android.app.Service#onCreate()
	 */
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		System.out.println("Service is Created.");
		// 创建并启动一个线程,动态修改count变量值
		new Thread() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				while (!isQuit) {
					try {
						Thread.sleep(1000);// 使得当前线程休眠1000毫秒
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					count++;
				}
			}
		}.start();
		super.onCreate();
	}

	/*
	 * (non-Javadoc)onStart方法已被onStartCommand方法代替,api不赞成使用
	 * 
	 * @see android.app.Service#onStart(android.content.Intent, int)
	 */
	@Override
	@Deprecated
	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);
	}

	// 在所有onUnbind被回调之后调用
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		System.out.println("Service is Destroyed.");
		isQuit = true;
		super.onDestroy();
	}

	// 定义一个返回实例名的方法
	public String getDemoName() {
		return "Service实例";
	}

	// 在所有与Service绑定的客户端都解除绑定之后被回调
	@Override
	public boolean onUnbind(Intent intent) {
		// TODO Auto-generated method stub
		System.out.println("Service is Unbind.");
		return true;// 表示下次客户端绑定的时候接受一个onRebind()的调用(而不是调用 onBind())
	}

	public void MyMethod() {
		for (int i = 0; i < 100; i++) {
			Log.i("44", "BindService-->MyMethod()");
		}
	}

}

 

xml文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.wang.servicedemo.MainActivity" >

    <Button
        android:id="@+id/btnBind"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="绑定service" />

    <Button
        android:id="@+id/btnGetServiceStatus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获得service状态" />

    <Button
        android:id="@+id/btnUnBind"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="解绑service" />

</LinearLayout>

 

最后在清单文件中声明service:

<service android:name="com.wang.servicedemo.BindService" >
            <intent-filter>

                <!-- 为该Service组件的intent-filter配置action ,用于隐式启动时使用-->
                <action android:name="com.wang.servicedemo.BIND_SERVICE" >
                </action>
            </intent-filter>
        </service>

 

 

 

 

Android 开发中,Service Thread 是两个用于处理后台任务的机制,但它们在用途、生命周期适用场景上有显著的区别。 ### 1. **基本概念与用途** ServiceAndroid 的四大组件之一,它主要用于执行长时间运行的操作,并且可以在后台持续运行,即使用户切换了应用或者 Activity 被销毁。Service 通常用于执行不需要与用户界面直接交互的任务,例如播放音乐、下载文件或处理网络请求[^2]。 Thread 是 Java 中的基本线程类,用于实现并发操作。在 Android 中,Thread 通常用于执行耗时任务,以避免阻塞主线程(UI 线程),从而防止应用出现 ANR(Application Not Responding)错误[^4]。 ### 2. **生命周期管理** Service 的生命周期由系统管理,可以通过 `startService()` 或 `bindService()` 启动。当 Service 被启动后,它会在后台持续运行,直到它自己调用 `stopSelf()` 或者其他组件调用 `stopService()` 来停止它[^3]。 Thread 的生命周期则完全由开发者控制。一旦 Thread 的 `run()` 方法执行完毕,或者开发者主动调用 `interrupt()` 方法,Thread 就会终止。如果 Thread 的创建者(例如一个 Activity)被销毁,而 Thread 仍在运行,那么该 Thread 将继续执行,但无法再被控制,除非手动停止或程序进程被终止[^3]。 ### 3. **线程与进程模型** Service 本质上是一个组件,它默认运行在应用的主线程中,因此不能直接在 Service 中执行耗时操作,否则会导致主线程阻塞。通常会在 Service 中启动一个 Thread 来处理耗时任务[^2]。 Thread 则是一个独立的执行单元,它可以运行在自己的线程中,不会阻塞主线程Thread 的运行是独立的,即使启动它的组件(如 Activity)被销毁,Thread 仍会继续执行,直到其任务完成或被显式中断[^3]。 ### 4. **跨组件通信与资源共享** Service 可以通过 `bindService()` 提供绑定接口,允许其他组件(如 Activity)与其进行通信交互。这种机制使得多个组件可以共享同一个 Service 实例,并对其进行控制。此外,Service 还可以通过 BroadcastReceiver 接收广播消息,从而实现更灵活的交互方式[^3]。 Thread 不具备跨组件通信的能力。Thread 的生命周期控制范围局限于创建它的组件。如果多个组件需要对同一个后台任务进行控制,Thread 无法满足这一需求,而 Service 则可以很好地解决这个问题[^3]。 ### 5. **适用场景** - **Service** 适用于需要长时间运行、跨组件控制的任务。例如,音乐播放器、后台数据同步服务等。 - **Thread** 适用于执行短期的、不需要跨组件控制的耗时任务。例如,图片加载、数据解析等。 ### 6. **代码示例** 以下是一个简单的 Thread 示例,用于执行耗时任务: ```java class MyThread extends Thread { @Override public void run() { try { sleep(3000); String s = "世界平"; Log.i("Thread方式收到的值是:", s); } catch (InterruptedException e) { e.printStackTrace(); } } } MyThread myThread = new MyThread(); myThread.start(); ``` 而 Service 的使用通常涉及以下几个步骤: ```java public class MyService extends Service { @Override public void onCreate() { super.onCreate(); // 初始化操作 } @Override public int onStartCommand(Intent intent, int flags, int startId) { // 执行后台任务 new Thread(new Runnable() { @Override public void run() { // 耗时操作 } }).start(); return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); // 清理资源 } @Override public IBinder onBind(Intent intent) { return null; } } ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值