您的位置:首页 > 移动开发 > Android开发

0909Android基础安卓四大组件之Service

2015-09-09 21:24 1036 查看

服务是什么

  服务(Service)是Android中实现程序后台运行的解决方案,它非常适合用于执行那些不需要和用户交互而且还需要长期运行的任务。服务的运行不依赖与用户界面,当程序被切换到后台,或者用户打开另一个应用程序,服务依然正常运行。

  服务依赖于创建服务时所在的应用程序进程。某个应用进程被杀掉时,依赖于该进程的服务也停止。

服务的生命周期



  左图是未绑定的服务的生命周期,右图是绑定服务的生命周期(暂不说明)

  未绑定的服务的生命周期。一旦在项目的任何位置调用了Context的startService()方法,相应的服务就会启动起来,并回调onStartCommand方法。如果这个服务之前没有创建,则onCreate()方法会先于onStartCommand()被调用。服务启动后会一直保持运行状态,直到stopService()或者stopSelf()方法被调用。每调用一次startService()方法,onStartCommand()就会执行一次,但实际上每个服务都只会存在一个实例。所以不管调用了多少次onStartCommand()方法,只需要调用一次stopService()或者stopSelf()方法,服务就会停止下来。

服务的基本用法

定义一个服务

  新建一个项目,然后在项目中新建一个类MyService继承Service,并复写三个方法,onCreate(),onStartCommand(),onDestory()。

  onCreate()方法会在服务创建的时候调用,onStartCommand()会在服务启动的时候调用,onDestory()会在服务销毁的时候调用。

  通常在onStartCommand()中写一些动作,在onDestory()中回收资源。

  另外,每一个服务都需要在AndroidMainfest.xml中注册才能生效,这是四大组件共有的特点。

  这个例子实现了点击启动服务后启动线程打开广播填满进度条的过程

注册

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.laowang.myservice" >

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService"/>
</application>
</manifest>


创建的类

  我在各个方法中加了一些toast,以便观察到现象。在启动服务中添加了一个线程。

public class MyService extends Service{
private int count;
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(getApplication(),"创建服务",Toast.LENGTH_SHORT).show();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplication(),"启动服务",Toast.LENGTH_SHORT).show();
new Thread(new Runnable() {
@Override
public void run() {
while(count<=100){
//                    if(count>100){
//                        count=0;
//                    }
count++;
//                    发送广播,和传进来的intent不一样,一个是发送广播的,一个是开启服务的。
Intent intent=new Intent();
intent.setAction(MainActivity.DOWNLOAD_RECEIVER);
intent.putExtra("count", count);
sendBroadcast(intent);

try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getApplication(),"关闭服务",Toast.LENGTH_SHORT).show();
}

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


启动和停止服务

  启动和停止服务的方法是借助Intent实现的。

启动服务

Intent intent1=new Intent(getApplicationContext(),MyService.class);
startService(intent1);


停止服务

Intent intent2=new Intent(getApplicationContext(),MyService.class);
stopService(intent2);


  这个例子的原理图

  


活动代码

public class MainActivity extends Activity implements View.OnClickListener{
private Button mServiceStart;
private Button mServiceStop;
private ProgressBar mProgressBar;
private MyDownloadReceiver myDownloadReceiver;
private IntentFilter intentFilter;
public static final String DOWNLOAD_RECEIVER="com.laowang.downloadReceiver";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mServiceStart= (Button) findViewById(R.id.service_start);
mServiceStop= (Button) findViewById(R.id.service_stop);

mProgressBar= (ProgressBar) findViewById(R.id.progerssbar);

// 注册广播
myDownloadReceiver=new MyDownloadReceiver();
intentFilter=new IntentFilter();
intentFilter.addAction(DOWNLOAD_RECEIVER);
registerReceiver(myDownloadReceiver, intentFilter);

mServiceStart.setOnClickListener(this);
mServiceStop.setOnClickListener(this);

}

@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.service_start:
Intent intent1=new Intent(getApplicationContext(),MyService.class); startService(intent1);
break;
case R.id.service_stop:
Intent intent2=new Intent(getApplicationContext(),MyService.class);
stopService(intent2);
break;
default:
break;
}
}
class MyDownloadReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
// 第二个参数为默认值,int类型的默认值为0
int count=intent.getIntExtra("count",0);
mProgressBar.setProgress(count);
}
}

//代码中注册广播要记得增加关闭的代码
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myDownloadReceiver);
}
}


布局

<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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">

<Button
android:id="@+id/service_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="启动服务"/>
<Button
android:id="@+id/service_stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="关闭服务"/>
<ProgressBar
android:id="@+id/progerssbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
android:progress="100"/>
</LinearLayout>


效果



服务的小技巧

IntentService

  非多线程,自身包含一个线程,可以直接加入耗时操作。包含一个消息队列。连续启动的话将任务存下来,按顺序一个一个的完成任务。自动回收资源,自动运行结束后destory,常用于后台进行一个耗时操作。

  新建一个类继承IntentService,只需要重写onHandleIntent()这个抽象方法,和构造器就够了。本例子中为了验证是否会自动destory,所以重写了销毁的方法。

public class MyIntentService extends IntentService {
private int count;
/**
* Creates an IntentService.  Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public MyIntentService(String name) {
super(name);
}
public MyIntentService(){
this("");
}

@Override
public void onDestroy() {
Log.d("注销", "onDestroy ");
super.onDestroy();
}

@Override
protected void onHandleIntent(Intent intent) {
Log.d("进入intentService", "╮(╯▽╰)╭");
if(count==100){
count=0;
}
while(count<100){
//                    if(count>100){
//                        count=0;
//                    }
count++;
//                    发送广播,和传进来的intent不一样,一个是发送广播的,一个是开启服务的。
Intent intent1=new Intent();
intent1.setAction(MainActivity.DOWNLOAD_RECEIVER);
intent1.putExtra("count", count);
sendBroadcast(intent1);

try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.d("完成intentService", "╮(╯▽╰)╭");
}
}


  然后在第一个例子加俩按钮启动服务。(启动停止服务方法和Service一样)

  能够看到效果和第一个例子一样,而且通过logcat也看到了它是能够自动关闭的。

参考文献:《第一行代码》,作者郭霖
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息