zoukankan      html  css  js  c++  java
  • 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下载

  • 相关阅读:
    Linux 常用命令
    去除重叠区间
    Python 小工具之大文件去重
    有趣的pyfiglet
    杨辉三角
    Paginator分页
    Linux用户和用户组
    Grub介绍
    Linux系统运行级别
    Linux系统启动流程
  • 原文地址:https://www.cnblogs.com/tornadomeet/p/2647381.html
Copyright © 2011-2022 走看看