Android开发历程_13(Service的使用)

 

  Service在android中的地位和activity,只是它没有单独的界面,一般都是在后台运行,主要是用来运行一些消耗时间比较长的任务。我们可以用它来发送intent来更新activity的UI。另外需要注意的是service既不是一个单独的进程,也不是一个单独的线程,它与activity一起在同一个进程中。

  关于android的sevice,网上这篇文章对service做了比较详细的介绍,并通过启动音乐播放器的例子来讲解service:http://www.cnblogs.com/allin/archive/2010/05/15/1736458.html

 

  Service的生命周期

  既然service和activity一样重要,则和activity类似,它也有自己的生命周期。它的生命周期与启动service的方式不同与不同,比如在activity中启动service时,如果采用的是         activity.startService()启动,则该service的生命周期一般为:

  onCreate()->onStart()/onStartCommand()->service running->onDestroy().

  如果是activity.bindService()启动,则该service的生命周期为:

  onCreate()->onBind()->service running->onUnbind()->onDestrop().

 

  实验部分

  本次实验主要是学习怎样在activity中启动一个service,启动的service的生命周期顺序是哪些,然后service通过广播机制向特定的activity传递数据,传送数据当然用的是intent,然后接收到该广播的activity读取intent中的数据,根据读取到的数据来更新activity的UI。

  关于怎样通过service广播机制来更新activity的UI,可以阅读网上的这篇文章:http://www.pocketdigi.com/20110303/197.html

  需要注意的是service类是继承的android框架中的Service类,程序中需要将写好的service在AndriodManiFest.xml中进行注册,注册方法和activity的注册类似。

  本程序的activity中有2个按钮和1个TextView,2个按钮分别用来启动service和停止service,然后在activtiy和service的生命周期函数中各自在后台打印出相关语句,同时为了方便观察,程序也直接将相关语句输出到了textview中。

 

  启动程序后,界面如下:

  

 

  单击一次start service按钮,然后单击一次end service,再单击一次start service按钮后,界面输出如下:

  

 

  后台输出如下:

  

 

 

程序主要部分代码和注释(附录有实验工程code下载链接):

MainActivity.java:

package com.example.service;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;



public class MainActivity extends Activity {

    private  TextView text = null;
    private  Button start = null;
    private  Button end = null;
    MyReceiver receiver;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        text = (TextView)findViewById(R.id.text);
        start = (Button)findViewById(R.id.start);
        start.setOnClickListener(new StartOnClickListener());
        end = (Button)findViewById(R.id.end);
        end.setOnClickListener(new EndOnClickListener());
        
        System.out.println("Activity onCreate");
        text.append("\nActivity onCreate...");
        
        //因为该activity要接收广播消息,所以先顶一个一个接收器对象
        //该对象自己实现,是继承BroadcastReceiver的
        receiver=new MyReceiver();
        //定义一个IntentFilter的对象,来过滤掉一些intent
        IntentFilter filter = new IntentFilter();
        //只接收发送到action为"android.intent.action.MAIN"的intent
        //"android.intent.action.MAIN"是在MainFest中定义的
        filter.addAction("android.intent.action.MAIN");
        //启动广播接收器
        MainActivity.this.registerReceiver(receiver, filter);
        
    }
    
    public class MyReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            
            Bundle bundle = intent.getExtras();
            if(bundle.getInt("i") == 1)
                text.append("\nService onBind...");
            else if(bundle.getInt("i") == 2)
                text.append("\nService onCreate...");
            else if(bundle.getInt("i") == 3)
                text.append("\nService onStartCommand...");
            else if(bundle.getInt("i") == 4)
                text.append("\nService onDestroy...");
    
        }       
    }

    private class StartOnClickListener implements OnClickListener
    {
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent intent = new Intent();
            //跳转到service用startService,以前跳转到activity用的是startactivity
            intent.setClass(MainActivity.this, FisrtService.class);
            //启动service
            startService(intent);
        }       
    }
    
    private class EndOnClickListener implements OnClickListener
    {
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent intent = new Intent();
            intent.setClass(MainActivity.this, FisrtService.class);
            //结束service
            stopService(intent);
        }       
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

 

FirstService.java:

package com.example.service;

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


//从Service类继承而来
public class FisrtService extends Service{

    Intent intent = new Intent();
    //intent.setAction("android.intent.action.MAIN");
    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        System.out.println("Service onBind");
        intent.putExtra("i", 1);
        //service设置需要接收广播intent的activity
        intent.setAction("android.intent.action.MAIN");
        //service通过广播发送intent
        sendBroadcast(intent);
        return null;
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        System.out.println("Service onCreate");
        intent.putExtra("i", 2);
        intent.setAction("android.intent.action.MAIN");
        sendBroadcast(intent);
        
    }

    //onStartCommand与onStart类似,多了一个参数而已
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        System.out.println("flags---->"+flags);
        System.out.println("startId---->"+startId);
        System.out.println("Service onStartCommand");
        
        //不懂为什么这里要重新开一个intent,它的activity才能接收到它
        Intent intent1 = new Intent();
        intent1.putExtra("i", 3);
        intent1.setAction("android.intent.action.MAIN");
        sendBroadcast(intent1);
        
//        //很奇怪为什么这里这样用,在activity中竟然接收不到该intent,一定要重新开一个intent?
//        intent.putExtra("i", 3);
//        intent.setAction("android.intent.action.MAIN");
//        sendBroadcast(intent);
        
        return super.onStartCommand(intent, flags, startId);
    }
    
    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        System.out.println("Service onDestroy");
        intent.putExtra("i", 4);
        intent.setAction("android.intent.action.MAIN");
        sendBroadcast(intent);
    }

}

 

Activity_main.xml:

<RelativeLayout 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" >

    <TextView
        android:id="@+id/text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello_service"
        android:layout_alignParentTop="true"
        />
    <Button
        android:id="@+id/end"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="@string/end"
        />
    <Button
        android:id="@+id/start"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        
          android:layout_above="@id/end"
        android:text="@string/start"
        />

</RelativeLayout>

 

 AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.service"
    android:versionCode="1"
    android:versionName="1.0" >

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

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

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

</manifest>

 

 

  总结:使用service可以在主界面运行的时候也能在后台运行多个服务,并且结合广播机制可以完成一些常见的功能。

 

  附录:

  实验工程code下载

 

 

 

 

 

 

作者:tornadomeet 出处:http://www.cnblogs.com/tornadomeet 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:tornadomeet,欢迎交流!)
posted on 2012-08-20 12:53  tornadomeet  阅读(4488)  评论(0编辑  收藏  举报

阿萨德发斯蒂芬