原文:http://blog.csdn.net/blueskydyliu/article/details/6557305
安卓作者的文章lz搭了个项目有兴趣的朋友可以去我群共享下载:250395324
lz其实是想做一个安卓推送的功能,无奈只能用service轮询的方式去实现,发现service的生命周期和程序不一样,可以在service中调用代码定时从服务器端获得推送的信息。
service的实现主要有两种方式,一种是onStart方式,另一种是onBoundd方式。两种方式的关于service的生命周期不一样。前者是和activity的生命周期一样的,后者则不是。activity结束了service可以继续运行。
onStart 方法来调用service的话,调用者其实和service是没有关系的,调用者消亡了的话,service是依然可以继续运行的;
onBound方式的话调用者和service是绑定在一起的,调用者消亡的了话,service也会跟着消亡了。
onStart 方法的创建的service一开始是onCreate 然后调用onStartCommand() (在老的版本中是onStart()函数,新版本中调用onStartCommand的话还是会去调用onStar方法,建议使用onStartCommand方式)。如果该service不stop的话,再点的话一直会是onstar相应,onCreate只有在第一次启动的时候会调用。
下面的例子:
有两个按钮:一个启动service,另一个停止service。具体实现如下:
1)ServiceText1.java
用于调用sercice程序:
代码:
- package com.huawei.android.servicetext1;
- 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;
- public class ServiceText1 extends Activity {
- private Button mbtnStarServ = null;
- private Button mbtnStopServ = null;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mbtnStarServ = (Button)findViewById(R.id.starService);
- mbtnStopServ = (Button)findViewById(R.id.stopService);
- mbtnStarServ.setOnClickListener(new listener());
- mbtnStopServ.setOnClickListener(new listener());
- }
- class listener implements OnClickListener
- {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Intent intent = new Intent(ServiceText1.this,Service.class);
- switch(v.getId())
- {
- case R.id.starService:
- //Intent intent = new Intent();
- //intent.setClass(ServiceText1.this, Service.class);
- startService(intent);
- break;
- case R.id.stopService:
- stopService(intent);
- break;
- default:
- break;
- }
- }
- }
- }
2)service.java,实现的service
- package com.huawei.android.servicetext1;
- import android.content.Intent;
- import android.os.IBinder;
- import android.util.Log;
- /**
- *
- * @author bluesky
- * @notes 创建一个service步骤
- * 1.简历一个service类,继承自Service类,
- * 2.复写onCreate,onDestory,onStartCommand函数。当需要onStartService方法来执行service方法的时候,
- * 这个时候onBind函数不需要执行任何操作,直接返回null就ok了
- * 3.在需要使用service的类得manifest.xml中进行注册。
- */
- public class Service extends android.app.Service {
- //创建service 需要复写 onCreate,onDestory,onStartCommand函数。这里是通过onStartService来执行service操作的,
- //这个时候onBind函数不需要执行任何操作,直接返回null就ok了
- private static final String TAG = "Service";
- @Override
- public void onCreate() {
- // TODO Auto-generated method stub
- Log.i(TAG, "Service------->onCreate");
- super.onCreate();
- }
- @Override
- public void onDestroy() {
- // TODO Auto-generated method stub
- Log.i(TAG, "Service------->onDestory");
- super.onDestroy();
- }
- //需要执行操作在onStartCommand里面来进行操作就可以了。
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- // TODO Auto-generated method stub
- Log.i(TAG, "Service------->onStartCommand");
- //这里的返回有三种类型,可以自己手动返回。return XXXXX;
- return super.onStartCommand(intent, flags, startId);
- }
- @Override
- public IBinder onBind(Intent arg0) {
- // TODO Auto-generated method stub
- return null;
- }
- }
3)ServiceText1.java
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.huawei.android.servicetext1"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="8" />
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".ServiceText1"
- 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=".Service">
- </service>
- </application>
- </manifest>
main.xml文件:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- />
- <Button
- android:id="@+id/starService"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/starservice"
- />
- <Button
- android:id="@+id/stopService"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/stopService"
- />
- </LinearLayout>
截图:
这里补充一点知识:
stop service 有两种方法:
1.使用调用程序来停止一个service :即调用stopService();
2.使用service 本身来停止一个service:即调用stopSelf(int srvId);
我们来想象一个场景:
如果service被很多的程序并发调用的话,如果在某个程序里你调用了stopService();那么第二个程序来调用的时候service的服务已经关掉了,这样你又得去重新onCreate()下service,如果量大的话,开销将是很大的。那么怎么办呢?
推荐的方式就是第二种了。stopSelf(int srvId),参数是srv的id,该id在startCommand的时候创建,stopSelf(int srvId)执行的时候会发送id给startCommand(),匹配所关掉服务的id是否匹配,这样如果某个启动服务的程序结束之前另一个线程也调用了startCommand(),这样前面一个程序就无法使用stopSelf(int srvId)来关闭service了。因为id已经变更了。这样就可以节约开销。