`
yangwei0915
  • 浏览: 463795 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

Android 中的服务初探

阅读更多

在很多情况下,一些与用户很少需要产生交互的应用程序,我们一般让它们在后台运行就行了,而且在它们运行期间我们仍然能运行其他的应用。

为了处理这种后台进程,Android引入了Service的概念。Service在Android中是一种长生命周期的组件,它不实现任何用户界面。最常见的例子如:媒体播放器程序,它可以在转到后台运行的时候仍然能保持播放歌曲;或者如文件下载程序,它可以在后台执行文件的下载。启动一个服务有两种方式,分别是采用startService方法和绑定Service的方式。在第一种方式启动后,Service会持续运行,直到调用stopService()或stopSelf()方法,如果调用方(例如在Activity中)销毁了,服务仍然还会运行。而第二种是先绑定后启动,绑定一个服务后调用方可以启动服务,并且能和服务依照定义的接口进行通信,并且还能接收服务方发送的广播消息,。我们先来看看第一种,在这个例子中我们实现一个使用Service播放音乐,在Activity界面上使用两个按钮, 分别控制服务的启动的停止。

 

使用startService方法启动服务

界面PlayActivity.java

package com.usestart.example;

import com.usestart.example.R;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class PlayActivity extends Activity implements OnClickListener {
  private static final String TAG = "com.example1.PlayActivity";
	Button buttonStart, buttonStop;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		buttonStart = (Button) findViewById(R.id.buttonStart);
		buttonStop = (Button) findViewById(R.id.buttonStop);

		buttonStart.setOnClickListener(this);
		buttonStop.setOnClickListener(this);
	}

	public void onClick(View src) {
		switch (src.getId()) {
		case R.id.buttonStart:
			Log.d(TAG, "onClick: starting srvice");
			startService(new Intent(this, PlayService.class));
			break;
		case R.id.buttonStop:
			Log.d(TAG, "onClick: stopping srvice");
			stopService(new Intent(this, PlayService.class));
			break;
		}
	}

	@Override
	protected void onDestroy() {
		Log.i(TAG, "----Activity is onDestroy");
		super.onDestroy();
	}
}

 
后台服务PlayService.java

package com.usestart.example;

import java.io.IOException;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class PlayService extends Service {
	private static final String TAG = "com.example.PlayService";
	MediaPlayer player;
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	@Override
	public void onCreate() {
		Toast.makeText(this, "Play Service Created", Toast.LENGTH_LONG).show();
		Log.d(TAG, "onCreate");
		
		player =new MediaPlayer();
		try {
			player.setDataSource("http://content.12530.com/upload/rings2/20090519/600618000223600902000001132715/000053488222_000019.mp3");
			player.prepare();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		player.setLooping(true); // Set looping
	}

	@Override
	public void onDestroy() {
		Toast.makeText(this, "Play Service Stopped", Toast.LENGTH_LONG).show();
		Log.d(TAG, "onDestroy");
		player.stop();
	}
	
	@Override
	public void onStart(Intent intent, int startid) {
		Toast.makeText(this, "Play Service onStart", Toast.LENGTH_LONG).show();
		Log.d(TAG, "onStart");
		player.start();
	}
}

 

在这个示例中我们演示了使用第一种方法启动一个服务,在界面上点击start按钮,后服务启动,音乐开始播放,点击Stop按钮服务停止和销毁,音乐停止播放。当点击手机上的回退按钮时我们发现Activity的onDestroy被调用,但是Service的onDestroy并未被调用,音乐也一直播放,直到再重新进入程序点击Stop按钮,服务的onDestroy才被调用。并且我们在界面上反复点击Start按钮,发现onStart回被多次调用,但是并没有多个音乐在播放,可以发现一个服务一旦启动了,再次调用star这个服务,onStart方法也被调用,但是不能导致再次启动这个服务。

 

使用bind方式来启动服务

 

package com.usebind.example;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class PlayActivity2 extends Activity implements OnClickListener{
	private static final String TAG = "com.example1.PlayActivity2";
	Button buttonStart, buttonStop;
	Intent serviceIntent;
	
	ServiceConnection conn = new ServiceConnection() {
	    @Override
	    public void onServiceConnected(ComponentName name, IBinder service) {
	        Log.i("INFO", "------------Service bind");
	    }

	    @Override
	    public void onServiceDisconnected(ComponentName arg0) {
	         Log.i("INFO", "--------Service unBind");
	    }

	};
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		buttonStart = (Button) findViewById(R.id.buttonStart);
		buttonStop = (Button) findViewById(R.id.buttonStop);

		buttonStart.setOnClickListener(this);
		buttonStop.setOnClickListener(this);
		serviceIntent = new Intent(this, PlayService.class);
		bindService(serviceIntent, conn, BIND_AUTO_CREATE);
	}

	public void onClick(View src) {
		switch (src.getId()) {
		case R.id.buttonStart:
			Log.d(TAG, "onClick: starting srvice");
			//startService(new Intent(this, PlayService.class));
			//bindService(new Intent("com.wissen.testApp.service.MY_SERVICE"), conn, Context.BIND_AUTO_CREATE);
			Intent i = new Intent(this, PlayService.class);   
			this.startService(i);   
			break;
		case R.id.buttonStop:
			Log.d(TAG, "onClick: stopping srvice");
			unbindService(conn);
			//只有unbind之后调用stop才能将服务停止
			stopService(new Intent(this, PlayService.class));
			break;
		}
	}

	@Override
	protected void onDestroy() {
		Log.d(TAG, "----Activity is onDestroy");
		unbindService(conn);
		super.onDestroy();
	}
}

 

使用bind方式方式时,在调用方调用bindService方法之后,服务并没有启动,只有在调用了startService方法之后服务才被启动。并且在Activity销毁时必须调用unbindService断开和这个服务的连接,否则程序回出错。如果是网速较慢或其他原因在运行上面的例子时回出现 no response错误,程序退出。导致这个原因是因为在service的onCreate方法是在主线程中运行的,不能出现运行耗时较长的代码,如果出现耗时较长的操作会将cpu阻塞住,这样很容易出现no response的错误.所以在编写一个服务时应将运行耗时较长的代码放到另外一个线程中或AsyncTask的doInBackground方法中执行。

在附件中ServicesPlay1是使用第一种方式,ServicesPlay1使用第二种方式的示例代码。

分享到:
评论

相关推荐

    Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明

    Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明 Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明 Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明

    Android单元测试初探——Instrumentation

    首先,我们来了解一下android的测试类的层次结构:可以看出android中的测试方法主要有AndroidTextCase和InstrumentationTextCase。在这篇文章中,我将介绍Instrumentation这种测试方法,那么什么是Instrumentation?...

    Android Apk解密工程初探

    Android Apk解密工程初探

    初探Android初探Android.doc

    开放手持装置联盟(Open Handset Alliance)由包括摩托罗拉、宏达电、三星、LG等在内的多家知名厂商共同成立,它们致力于基于Android平台开发新的智能手机和服务。 Android SDK(软件开发工具包)是Google为了方便...

    android多媒体框架初探

    这个是我在华为进行培训自己写的ppt,欢迎下载.

    Android TensorFlow Lite 初探 数字分类器

    Android TensorFlow Lite 初探 数字分类器 非kotlin 相关文章:https://blog.csdn.net/ansondroider/article/details/108508065 修改后的JAVA代码

    Android fragment懒加载初探

    在Android应用开发中,Fragment是Activity的一个模块化组件,它允许开发者将屏幕的不同部分独立管理。"Android fragment懒加载"是指在用户实际需要时才加载Fragment中的数据或视图,而不是在Fragment创建时立即加载...

    关于android AppWidget初探①

    - `RemoteViews`:用于构建和修改AppWidget的视图结构,它可以操作位于远程服务中的视图,确保安全性和性能。 3. **创建AppWidget的步骤** - 首先,在`AndroidManifest.xml`中声明`AppWidgetProvider`,并提供`...

    Android Apk解密工程初探(打包)

    Android Apk解密工程初探(打包)

    Kotlin初探与集成Android项目

    ### Kotlin初探与集成Android项目 #### 一、了解Kotlin **Kotlin的背景:** Kotlin 是一种由 JetBrains 开发的静态类型编程语言,它最初发布于 2011 年,并且在 2017 年被 Google 宣布成为 Android 的官方开发...

    Android开发常用技术初探.pdf

    《Android开发常用技术初探》 在移动互联网的飞速发展中,Android系统占据了智能手机市场的主要份额,成为开发者和用户关注的焦点。Android以其开源、灵活的特性吸引了众多开发者,不断推动着应用程序的创新和发展...

    入门--初探Android

    "入门--初探Android" Android是一个基于Linux核心(kernel)的开源手机操作系统平台。它于2007年11月5日由Google与其他33家手机制造商、手机晶片供应商、软件供应商、电信运营商所组成的开放手机联盟(Open Handset ...

    Android自动化测试初探.doc

    【Android自动化测试初探】 Android自动化测试是一种针对Android应用程序进行的自动化的质量验证过程,它旨在减少手动测试的重复劳动,提高测试效率和覆盖率。在Android系统中,自动化测试通常涉及UI测试、功能测试...

    基于Scrum的Android教学改革初探.pdf

    【基于Scrum的Android教学改革】是针对当前Android应用开发教育中存在的问题,如传统项目化教学方式无法有效培养学生的团队协作精神、岗位需求理解和多元评价方式的缺失,提出的一种新型教学模式。Scrum是一种敏捷...

    Android自动化测试初探

    首先,我们了解到传统的Android自动化测试通常依赖于JUnit框架和Android SDK中的`android.test`包,但这需要应用程序的源代码,这对于许多只做黑盒测试的测试工程师来说并不实际。 Android系统中的权限控制严格限制...

    三、初探Android开发-Android开发与实践

    1. 选择`File` -> `New` -> `Project...`,然后在弹出的窗口中选择`Android` -> `Android Project`,或者通过`File` -> `New` -> `Other...`,然后选择`Android` -> `Android Project`。 2. 输入唯一的工程名称,...

Global site tag (gtag.js) - Google Analytics