Android中的Service概念及用途

Android中的Service概念及用途
Android中的Service概念及用途

Service概念及用途

Android中的Service,其意思是“服务”,它是在后台运行,不可交互的。Service自己不能运行,需要通过某一个Activity或者其它Context对象来调用,如Context .startService() 和Context.bindService()两种方式启动Service 。

Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行,那我们什么时候会用到Service呢?比如我们播放音乐的时候,有可能想边听音乐边干些其他事情,当我们退出播放音乐的应用,如果不用Service,我们就听不到歌了,所以这时候就得用到Service了,又比如当我们一个应用的数据是通过网络获取的,不同时间(一段时间)的数据是不同的这时候我们可以用Service在后台定时更新,而不用每打开应用的时候在去获取。

如果在Service的onCreate或者onStart方法中做一些很耗时的动作,最好是启动一个新线程来运行这个Service,因为,如果Service运行在主线程中,会影响到程序的UI操作或者阻塞主线程中的其它事情。

Service生命周期

Service的生命周期方法比Activity要少一些,只有onCreate、onStart、onDestroy。有两种方式启动一个Service,他们对Service生命周期的影响是不一样的。

1)通过startService启动

Service启动的时候会经历生成开始(onCreate onStart)过程,Service

停止的时候直接进入销毁过程(onDestroy)。而如果是调用者直接退出而没有调用stopService,Service会一直在后台运行。直到下次调用者再启动起来,并明确调用stopService。

2)通过bindService启动

通过bindService方法启动Service,其只会运行onCreate方法,如果调用退出了,Service会调用onUnbind,onDestroyed方法。Service的onCreate

方法只会被调用一次。如果先绑定了,那么启动的时候就直接运行Service的onStart方法,如果先启动,那么绑定的时候就直接运行onBind方法。如果先绑定上了,就停止不了,也就是stopService不能用了,只能先unbindService ,

再stopService,所以,先启动还是先绑定,是有区别的。

示例1

下面以一个通过Service来播放音乐的例子说明Service的具体用法,其具体界面如下所示:在这个界面中,点击“Start Playing”按钮,即开始打开音乐文件,进行循环播放。点击“Stop Playing”按钮,即关闭音乐,并退出应用程序。其程序结构如下图所示:

可以看到,其功能主要由Music与TestMusicService两个类组成,其源代码如下:

package com.shen.service;

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;

public class TestMusicService extends Activity {

private TextView tv;

private Button btn1,btn2;

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(https://www.360docs.net/doc/a118525170.html,yout.main);

btn1 = (Button) this.findViewById(R.id.btn1);

btn1.setOnClickListener(new ButtonListener1());

btn2 = (Button) this.findViewById(R.id.btn2);

btn2.setOnClickListener(new ButtonListener2());

}

private class ButtonListener1 implements OnClickListener{

public void onClick(View v) {

TestMusicService.this.startService(new Intent("com.shen.music1"));

}

}

private class ButtonListener2 implements OnClickListener{

public void onClick(View v) {

TestMusicService.this.stopService(new Intent("com.shen.music1"));

finish();

}

}

}

package com.shen.service;

import android.app.Service;

import android.content.Intent;

import android.media.MediaPlay er;

import android.os.IBinder;

public class Music extends Service {

private MediaPlay er mp;

public IBinder onBind(Intent intent) {

return null;

}

public void onStart (Intent intent, int startId) {

super.onStart(intent, startId);

if (mp != null){

mp.stop();

}

mp = MediaPlayer.create(this,R.raw.music_1);

mp.setLooping(true);

mp.start();

}

public void onDestroy () {

super.onDestroy();

mp.stop();

mp = null;

}

}

另外,需要在Manifest.xml文件中对Service进行注册。其注册信息如下所示:

package="com.shen.service"

android:versionCode="1"

android:versionName="1.0">

android:label="@string/app_name">

android:label="@string/app_name">

示例2:Service与Activity通信:

Service后端的数据最终还是要呈现在前端Activity之上的,因为启动Service时,系统会重新开启一个新的进程,这就涉及到不同进程间通信的问题了(AIDL)这一节我不作过多描述,当我们想获取启动的Service实例时,我们可以用到bindService和onBindService方法,它们分别执行了Service中IBinder()和onUnbind()方法。

为了让大家更容易理解,我写了一个简单的Demo,大家可以模仿,一步一步的来。第一步:新建一个Android工程,命名为ServiceDemo.

第二步:修改main.xml代码,这里增加了四个按钮,代码如下:

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

android:id="@+id/text"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/hello"

/>

android:id="@+id/startservice"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="startService"

/>

android:id="@+id/stopservice"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="stopService"

/>

android:id="@+id/bindservice"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="bindService"

/>

android:id="@+id/unbindservice"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="unbindService"

/>

第三步:新建一个Service,命名为MyService.java代码如下:

package com.tutor.servicedemo;

import android.app.Service;

import android.content.Intent;

import android.os.Binder;

import android.os.IBinder;

import android.text.format.Time;

import android.util.Log;

public class MyService extends Service {

//定义个一个Tag标签

private static final String TAG = "MyService";

//这里定义一个Binder类,用在onBind()有方法里,这样Activity那边可以获取到private MyBinder mBinder = new MyBinder();

@Override

public IBinder onBind(Intent intent) {

Log.e(TAG, "start IBinder~~~");

return mBinder;

}

@Override

public void onCreate() {

Log.e(TAG, "start onCreate~~~");

super.onCreate();

}

@Override

public void onStart(Intent intent, int startId) { Log.e(TAG, "start onStart~~~");

super.onStart(intent, startId);

}

@Override

public void onDestroy() {

Log.e(TAG, "start onDestroy~~~");

super.onDestroy();

}

@Override

public boolean onUnbind(Intent intent) {

Log.e(TAG, "start onUnbind~~~");

return super.onUnbind(intent);

}

//这里我写了一个获取当前时间的函数

public String getSystemTime(){

Time t = new Time();

t.setToNow();

return t.toString();

}

public class MyBinder extends Binder{

MyService getService()

{

return MyService.this;

}

}

}

第四步:修改ServiceDemo.java,代码如下: package com.tutor.servicedemo;

import android.app.Activity;

import https://www.360docs.net/doc/a118525170.html,ponentName;

import android.content.Context;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.Bundle;

import android.os.IBinder;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;

public class ServiceDemo extends Activity implements OnClickListener{

private MyService mMyService;

private TextView mTextView;

private Button startServiceButton;

private Button stopServiceButton;

private Button bindServiceButton;

private Button unbindServiceButton;

private Context mContext;

//这里需要用到ServiceConnection在Context.bindService和

context.unBindService() 里用到

private ServiceConnection mServiceConnection = new ServiceConnection() { //当bindService,让TextView显示MyService里getSystemTime()方法的返回值public void onServiceConnected(ComponentName name, IBinder service) { mMyService = ((MyService.MyBinder)service).getService();

mTextView.setText("I am frome Service :" +

mMyService.getSystemTime());

}

public void onServiceDisconnected(ComponentName name) {

}

};

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(https://www.360docs.net/doc/a118525170.html,yout.main);

setupViews();

}

public void setupViews(){

mContext = ServiceDemo.this;

mTextView = (TextView)findViewById(R.id.text);

startServiceButton = (Button)findViewById(R.id.startservice);

stopServiceButton = (Button)findViewById(R.id.stopservice);

bindServiceButton = (Button)findViewById(R.id.bindservice);

unbindServiceButton = (Button)findViewById(R.id.unbindservice);

startServiceButton.setOnClickListener(this);

stopServiceButton.setOnClickListener(this);

bindServiceButton.setOnClickListener(this);

unbindServiceButton.setOnClickListener(this);

}

public void onClick(View v) {

// TODO Auto-generated method stub

if(v == startServiceButton){

Intent i = new Intent();

i.setClass(ServiceDemo.this, MyService.class);

mContext.startService(i);

}else if(v == stopServiceButton){

Intent i = new Intent();

i.setClass(ServiceDemo.this, MyService.class);

mContext.stopService(i);

}else if(v == bindServiceButton){

Intent i = new Intent();

i.setClass(ServiceDemo.this, MyService.class);

mContext.bindService(i, mServiceConnection, BIND_AUTO_CREATE);

}else{

mContext.unbindService(mServiceConnection);

}

}

}

第五步:修改AndroidManifest.xml代码(将我们新建的MyService注册进去如下代码第14行:)

package="com.tutor.servicedemo"

android:versionCode="1"

android:versionName="1.0">

android:label="@string/app_name">

android:label="@string/app_name">

第六步:执行上述工程,效果图如下:

点击startServie按钮时先后执行了Service中onCreate()->onStart()这两个方法,打开Logcat视窗效果如下图:

我们这时可以按HOME键进入Settings(设置)->Applications(应用)->Running Services(正在运行的服务)看一下我们新启动了一个服务,效果如下:

点击stopService按钮时,Service则执行了onDestroy()方法,效果图如下所示:

这时候我们再次点击startService按钮,然后点击bindService按钮(通常bindService都是bind已经启动的Service),我们看一下Service执行了IBinder()方法,以及TextView的值也有所变化了,如下两张图所示:

最后点击unbindService按钮,则Service执行了onUnbind()方法,如下图所示:

3. 几个需要注意的地方

1) Service无论以何种方式创建,都是在应用的主线程里创建的,也就是说创建一个Service并不意味着生成了一个新的线程,Service的创建过程是阻塞式的,因此也需要考虑性能,不能影响界面和逻辑上的后续操作。

2) 如果Service自己没有生成新的线程,那它也是运行在应用的主线程里的,因此Service本身并不能提高应用的响应速度和其他的性能,而是说通过这个后台服务生成新的线程来处理比较耗时的操作如大数据的读取等来提高响应,Service自己并不能保证这一点。Service相当于提供了一个这些费时操作的平台,由它在后台创建新线程完成这些任务,以及视各种情况管理这些线程,包括销毁。

3) stopService和unbindService都可以把Service停掉,但是如果希望明确立刻停掉Service,则使用stopService更安全,因为unbindService实质上是将与Service的连接数减一,当减为0的时候才会销毁该服务实例,stopService的效果相当于将连接数立即减为0,从而关闭该服务,所以在选择关闭方式上要视不同情况而定。

Android项目文档

课程代号:83308113 2014-2015学年第1学期《ISAS与项目训练(一)》 项目:Android 班级:网络2班 学号: 13734214 姓名:刘雨亭. 指导教师:温一军周洪斌 . 沙洲职业工学院 NIIT安艾艾迪

目录 一、系统简介 (3) 二、发展历程 (3) 三、发行版本 (4) 四、国内外手机应用状况 (4) 五、发展趋势 (5) 六、Android的相关技术介绍及分析 (6) 6.1、Android系统架构研究 (6) 6.2、应用程序框架 (7) 6.3、类库 (8) 七、Android的API (10) 八、Android活动的生命周期 (11)

一、系统简介 Android的Logo是由Ascender公司设计的,诞生于2010年,其设计灵感源于男女厕所门上的图形符号,于是布洛克绘制了一个简单的机器人,它的躯干就像锡罐的形状,头上还有两根天线,Android小机器人便诞生了。其中的文字使用了Ascender 公司专门制作的称之为“Droid ”的字体。Android是一个全身绿色的机器人,绿色也是Android的标志。颜色采用了PMS 376C和RGB中十六进制的#A4C639来绘制,这是Android操作系统的品牌象徵。有时候,它们还会使用纯文字的Logo。 二、发展历程 2003年10月,Andy Rubin等人创建Android公司,并组建Android团队。 2005年8月17日,Google低调收购了成立仅22个月的高科技企业Android及其团队。安迪鲁宾成为Google公司工程部副总裁,继续负责Android项目。 2007年11月5日,谷歌公司正式向外界展示了这款名为Android的操作系统,并且在这天谷歌宣布建立一个全球性的联盟组织,该组织由34家手机制造商、软件开发商、电信运营商以及芯片制造商共同组成,并与84家硬件制造商、软件开发

android 自定义圆角头像以及使用declare-styleable进行配置属性解析

android 自定义圆角头像以及使用declare-styleable进行配置属性解析由于最新项目中正在检查UI是否与效果图匹配,结果关于联系人模块给的默认图片是四角稍带弧度的圆角,而我们截取的图片是正方形的,现在要给应用统一替换。应用中既用到大圆角头像(即整个头像是圆的)又用到四角稍带弧度的圆角头像,封装一下以便重用。以下直接见代码 [java] view plain copy 在CODE上查看代码片派生到我的代码片 package com.test.demo; import com.test.demo.R; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Shader.TileMode; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.widget.ImageView; /** * 圆角imageview */ public class RoundImageView extends ImageView { private static final String TAG = "RoundImageView"; /** * 图片的类型,圆形or圆角 */ private int type; public static final int TYPE_CIRCLE = 0; public static final int TYPE_ROUND = 1; /** * 圆角大小的默认值

android studio 控件常用属性

android studio 控件常用属性 下面是RelativeLayout各个属性 1.android:layout_above="@id/xxx" --将控件置于给定ID控件之上 2.android:layout_below="@id/xxx" --将控件置于给定ID控件之下 3. android:layout_toLeftOf="@id/xxx" --将控件的右边缘和给定ID控件的左边缘对齐 4.android:layout_toRightOf="@id/xxx" --将控件的左边缘和给定ID控件的右边缘对齐 5. android:layout_alignLeft="@id/xxx" --将控件的左边缘和给定ID控件的左边缘对齐 6.android:layout_alignTop="@id/xxx" --将控件的上边缘和给定ID控件的上边缘对齐 7.android:layout_alignRight="@id/xxx" --将控件的右边缘和给定ID控件的右边缘对齐 8.android:layout_alignBottom="@id/xxx" --将控件的底边缘和给定ID控件的底边缘对齐 9.android:layout_alignParentLeft="true" --将控件的左边缘和父控件的左边缘对齐 10. android:layout_alignParentTop="true" --将控件的上边缘和父控件的上边缘对齐 11. android:layout_alignParentRight="true" --将控件的右边缘和父控件的右边缘对齐 12.android:layout_alignParentBottom="true" --将控件的底边缘和父控件的底边缘对齐 13.android:layout_centerInParent="true" --将控件置于父控件的中心位置 14.android:layout_centerHorizontal="true" --将控件置于水平方向的中心位置 15.android:layout_centerVertical="true" --将控件置于垂直方向的中心位置 android:layout_width 设置组件的宽度 android:layout_height 设置组件的高度 android:id 给组件定义一个id值,供后期使用 android:background 设置组件的背景颜色或背景图片 android:text 设置组件的显示文字 android:textColor 设置组件的显示文字的颜色 android:layout_below 组件在参考组件的下面 android:alignTop 同指定组件的顶平行

Android平台我的日记设计文档

Android平台我的日记 设计文档 项目名称:mydiray 项目结构示意: 阶段任务名称(一)布局的设计 开始时间: 结束时间: 设计者: 梁凌旭 一、本次任务完成的功能 1、各控件的显示 二、最终功能及效果 三、涉及知识点介绍 四、代码设计 activity_main.xml:

android:layout_centerHorizontal="true" android:layout_marginTop="88dp" android:text="@string/wo" android:textSize="35sp"/>

相关文档
最新文档