Android学习笔记入门 : 02Service

Service

概念: 

文档地址 :http://developer.android.com/reference/android/app/Service.html

Service 是用来执行长时间后台功能的组件 

Service 是在主线程中,若Service中使用长时间占用CPU的功能则需要使用多线程.


1 创建一个Service

首先建立一个继承android.app.Service的类

再去AndroidManifest.xml中的Application结点下建立一个Service

  <service android:name="cn.zyh.usingservice.EchoService"></service>

这个有两种方法.

1 )是直接将这行写入Xml文件的<Application> 结点下

2) 是 使用android提供的图形化界面


在Application Nodes这栏点Add,添加一个Service结点.

再在右边的Name属性中写上名称.


2 启动Service

首先创建一个代表该动作的Intent 

serviceIntent = new Intent(this, EchoService.class);

启动和运行分别使用 Context.startService() and Context.bindService().

启动服务 startService(serviceIntent);

停止服务 stopService(serviceIntent);

当启动后 可以在手机的设置-应用程序-正在运行的服务中看到Service


使用StartService启动的服务 ,即使应用退出,Service仍然会继续执行.

启动和停止Service分别会调用Service类中的onCreate和onDestory方法



3 绑定服务

使用bindService启动, 可以让服务随着应用启动和关闭.

也可以先startService 再 bindService. 


绑定服务的好处是可以让使用服务的对象调用服务中的方法. 


 使用 Context.bindService() 和 Context.unBindService() 来绑定和解绑服务.

这两个方法分别会调用Service对象的onCreate onBind方法和 onUnbind onDestory方法

bindService(serviceIntent, this, Context.BIND_AUTO_CREATE);
unbindService(this);

注意bindService 的第二个参数是一个 ServiceConnection接口对象,我们一般让你的Activity实现ServiceConnection.

需要实现2个方法 

@Override
public void onServiceConnected(ComponentName name, IBinder binder)
{
// Service 成功连接后
System.out.println("onServiceConnected");
}


@Override
public void onServiceDisconnected(ComponentName name)
{
// Service 崩溃时触发,不是通过unBind方法.
}


若是你的Service对象中的onBind()方法返回null,是不会触发onServiceConnected函数的.

onBind是Service对象中的一个需要实现的方法 ,返回值是IBinder对象,但是IBinder接口已经有一个实现类了Binder.

所以返回一个继承Binder的对象就行了.

@Override
public IBinder onBind(Intent intent)
{
System.out.println("onBind");
return echoServiceBinder;
}


关于解绑后服务还继不继续运行,根据网友的讨论我再验证了下是这样的:

有三种情况:如果直接使用服务,则没有必要进行绑定,但是如果要使用服务里面的方法,则要进行绑定。具体的启动情况有下:
 1.当启动时,单独调用bindService方法,在unbindService后,会执行service的onUnbind,在执行onDestroy方法。  2.当启动时,先调用startService,在调用bindService方法后,在unbindService后,会执行service的onUnbind,不会执行onDestroy方法。除非你在执行stopService.  3. 先调用startService,在调用stopService,会执行service的onDestroy方法。


另外就是无论你是通过startService还是bindService启动的服务,都只会存在一个对象,多次启动或者多次绑定是没有副作用的.


4 调用Service的函数

我们绑定服务就是为了调用服务中的方法,

@Override
public IBinder onBind(Intent intent)
{
System.out.println("onBind");
return echoServiceBinder;
}

 关键就是通过service中的onBind()方法返回的对象来调用

建立一个内部类 ,使其有一个公开的方法 返回外部类对象

public class EchoServiceBinder extends Binder
{
public EchoService getService()
{
return EchoService.this;
}
}

在绑定service的Activity (实现ServiceConnection类 ) 中重写onServiceConnected方法 

@Override
public void onServiceConnected(ComponentName name, IBinder binder)
{
 System.out.println("onServiceConnected");

  this.service = ((EchoServiceBinder) binder).getService();
}

这样 就获得了Service对象

调用其中方法那就不用说了.

 


=======================================



Activity

package cn.zyh.usingservice;

import cn.zyh.usingservice.EchoService.EchoServiceBinder;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.support.v4.widget.SimpleCursorAdapter.ViewBinder;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener,
		ServiceConnection
{

	private Button btnStartService, btnStopService, btnBindService,
			btnUnbindService, btnGetCountNum;
	private Intent serviceIntent;
	private EchoService service;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		btnStartService = (Button) findViewById(R.id.btnStartSer);
		btnStopService = (Button) findViewById(R.id.btnStopSer);
		btnStartService.setOnClickListener(this);
		btnStopService.setOnClickListener(this);
		serviceIntent = new Intent(this, EchoService.class);

		btnBindService = (Button) findViewById(R.id.bind);
		btnUnbindService = (Button) findViewById(R.id.unbind);
		btnBindService.setOnClickListener(this);
		btnUnbindService.setOnClickListener(this);

		btnGetCountNum = (Button) findViewById(R.id.getCount);
		btnGetCountNum.setOnClickListener(this);

	}

	@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 void onClick(View v)
	{
		switch(v.getId())
		{
			case R.id.btnStartSer:
				startService(serviceIntent);
				break;
			case R.id.btnStopSer:
				stopService(serviceIntent);
				service = null;
				break;
			case R.id.bind:
				bindService(serviceIntent, this, Context.BIND_AUTO_CREATE);
				break;
			case R.id.unbind:
				unbindService(this);
				service = null;
				break;
			case R.id.getCount:
				if (service != null)
				{
					System.out.println("count:" + service.getNum());
				}
			default:
				break;
		}
	}

	@Override
	public void onServiceConnected(ComponentName name, IBinder binder)
	{
		// Service成功连接后
		System.out.println("onServiceConnected");
		this.service = ((EchoServiceBinder) binder).getService();
	}

	@Override
	public void onServiceDisconnected(ComponentName name)
	{
		System.out.println("onServiceDisConnected");
		// Service 被关闭或崩溃时触发

	}
}
Service

package cn.zyh.usingservice;

import java.util.Timer;
import java.util.TimerTask;

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

public class EchoService extends Service
{

	@Override
	public void onCreate()
	{
		System.out.println("ONCREATE");
		super.onCreate();
		startTimer();
	}

	@Override
	public void onDestroy()
	{
		System.out.println("ONDESTORY");
		super.onDestroy();
		stopTimer();
	}

	@Override
	public boolean onUnbind(Intent intent)
	{
		System.out.println("unBind");
		return super.onUnbind(intent);
	}

	private final EchoServiceBinder echoServiceBinder = new EchoServiceBinder();

	public class EchoServiceBinder extends Binder
	{
		public EchoService getService()
		{
			return EchoService.this;
		}
	}

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

	private Timer timer = null;
	private TimerTask task;

	private int i = 0;

	public void startTimer()
	{
		if (timer == null)
		{
			timer = new Timer();
			task = new TimerTask()
			{
				@Override
				public void run()
				{
					i++;
				}
			};
		}

		timer.schedule(task, 1000, 1000);
		// 延迟1秒 每隔1秒执行一次
	}

	public void stopTimer()
	{
		task.cancel();
		if (timer != null)
		{
			timer.cancel();
		}
		task = null;
		timer = null;
	}

	public int getNum()
	{
		return i;
	}
}

AndroidManifest.XML

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.zyh.usingservice"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="8" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name="cn.zyh.usingservice.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="cn.zyh.usingservice.EchoService"></service>
    </application>

</manifest>







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值