Android学习笔记---Service及IntentService理解

Android学习笔记---Service及IntentService理解

一.Android Service服务:

      Android中的服务是运行在后台的服务,他是不可见的没有界面的东西。你可以启动一个服务Service来播放音乐,或者记录你地理信息位置的改变,或者启动一个服务来运行并一直监听某种动作。Service和其他组件一样,都是运行在主线程中,因此不能用它来做耗时的请求或者动作。你可以在服务中开一一个线程,在线程中做耗时动作。

服务的生命周期图:

 

 

1.如何创建和开启一个服务:

第一步:创建一个类 ExampleService.java 继承android.app.Service

第二步:覆盖其中继承的方法 如下:

 

public class ExampleService extends Service
{

    private static final String TAG = "Example";

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

    @Override
    public void onCreate()
    {
        Log.i(TAG, "ExampleService===>>onCreate");
        super.onCreate();
    }

    @Override
    public void onStart(Intent intent, int startId)
    {
        Log.i(TAG, "ExampleService===>>onStart");

        super.onStart(intent, startId);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        Log.i(TAG, "ExampleService===>>onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy()
    {
        Log.i(TAG, "ExampleService===>>onDestroy");
        super.onDestroy();
    }

}

 

第三步:启动服务:

    Intent intent = new Intent(MainActivity.this, ExampleService.class);
    startService(intent);

第四步:关闭服务:

stopService(intent);//关闭服务

服务运行的生命周期顺序:

[onCreate()-->onStartCommand()--->onStart()-->运行服务--->调用stopService()--->onDestory()]

在Activity中通过startService()开启的服务,开启之后及时现在我们关闭Activity服务还一直在后台运行,只有调用stopService()才能关闭服务。

关闭Activity之后 我们在此点击按钮 重新开启服务。

注意:服务在后台运行我们再次点击startService()开启服务。将不会在调用 onCreate()服务。一个服务只会创建一次,销毁一次,但可以开始多次,因此,onCreate和onDestroy方法只会被调用一次,而onStart(或onStartCommand)方法会被调用多次。

如下图:

 

 

点击stopService()方法将关闭服务:

 

 注意:onStart方法是在Android2.0之前的平台使用的.在2.0及其之后,则需重写onStartCommand方法,同时,旧的onStart方法则不会再被调用.    

 

 

 

二.bindService()

 

      Bound service 允许其它的组件(比如Activities)绑定到这个Service上,可以发送请求,也可以接受请求,甚至进行进程间的通话。Bound service 仅仅在服务于其它组件时存在,不能独自无限期的在后台运行。

 

 

     调用者和服务绑在一起,调用者一旦退出服务也就终止[onCreate()-->onBind()-->onUnbind()-->onDestory()]

1.创建Bound Services

 

     当创建一个能提供绑定功能的服务时,我们必须提供一个IBinder对象,客户端能使用这个对象与服务进行交互。在Android中有三种方式定义方式:

         1.扩展Binder类

         2.使用Messenger

         3.使用AIDL (Android Interface Definition Language)

   创建 步骤:

      第一步:.创建一个类BinderService.java 继承 android.app.Service

public class BinderService extends Service
{

    public class MyBinder extends Binder
    {
        public BinderService getBinderService()
        {
            return BinderService.this;
        }
    }
    private MyBinder binder=new MyBinder();
    private static final String TAg = "BinderService";
    @Override
    public IBinder onBind(Intent intent)
    {
        Log.i(TAg, "BinderService===>onBind()");
        return binder;
    }
    public void UpFile()
    {
        Log.i(TAg, "BinderService===>UpFile()");
    }
    @Override
    public void onCreate()
    {
        Log.i(TAg, "BinderService===>onCreate()");
        super.onCreate();
    }
    @Override
    public void onDestroy()
    {
        Log.i(TAg, "BinderService===>onDestroy()");
        super.onDestroy();
    }
    @Override
    public boolean onUnbind(Intent intent)
    {
        Log.i(TAg, "BinderService===>onUnbind()");
        return super.onUnbind(intent);
    }
    

}

 

第二步:在Service类中,创建一个Binder实例 包含客户端能调用的公共方法 返回当前服务对象

 

  

public class MyBinder extends Binder
    {
        public BinderService getBinderService()
        {
            return BinderService.this;
        }
    }

第三步:在onBind()方法中返回Binder实例

    private MyBinder binder=new MyBinder();
    private static final String TAg = "BinderService";
    @Override
    public IBinder onBind(Intent intent)
    {
        return binder;
    }

第四步:在客户端,从onServiceConnected()方法中获得Binder实例。

private void bindService()
    {
        Intent intent=new Intent(MainActivity.this,BinderService.class);
        bindService(intent,conn,Context.BIND_AUTO_CREATE);
    } 
   private void unBind()
   {
       if(isConnected)
       {
           unbindService(conn);
       }
   }
    private ServiceConnection conn=new ServiceConnection()
    {
        @Override
        public void onServiceDisconnected(ComponentName name)
        {
           isConnected=false;
            
        }
        @Override//在onServiceConnected 中获取Binder的实例
        public void onServiceConnected(ComponentName name, IBinder binder)
        {
            MyBinder myBinder=(MyBinder)binder;
            BinderService service=myBinder.getBinderService();
            service.UpFile();
            isConnected=true;
        }
    };

通过调用 bindService()开启服务 。

调用unBind()关闭服务,或者我们关闭Activity也会关闭服务

 

三.Android中Service运行在主线程中。

    Android 中的服务是运行在主线程上的,通过下面的例子来说明Android服务运行的线程。如果是运行在主线程的,

那在服务中步要运行太耗时的操作。如果运行态耗时的操作将会是整个Activity处于假死状态,无在进行别的操作。如何要运行耗时操作

要用到多线程Thread 或者异步操作 InentService.

创建一个 MyServiceThread.java 继承 Service的服务:

 

public class MyServiceThread extends Service
{

    private static final String TAG = "MyServiceThread";

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

    @Override
    public void onCreate()
    {
        Log.i(TAG, "MyServiceThread===>>onCreatre===>>线程ID:"+Thread.currentThread().getId());
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
    
        try
        {
//这里进行耗时的操作 Log.i(TAG,
"MyServiceThread===>>onStartCommand===>>线程ID:"+Thread.currentThread().getId()); Log.i(TAG, "文件下载。。。。。"); Thread.sleep(5000); Log.i(TAG, "文件下载完成。"); } catch (InterruptedException e) { e.printStackTrace(); } return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Log.i(TAG, "MyServiceThread===>>onDestroy===>>线程ID:"+Thread.currentThread().getId()); super.onDestroy(); } }

 

程序为开启耗时服务时:

    开启耗时服务时:

运行截图:下图可看出Android 中的Service确实是运行在主线程中。从运行前和运行后,当我们点击开启服务,按钮在服务没有运行

结束时,背景处于黄色,此时不能进行其他的操作。如果要运行耗时的操作需要应用多线程操作。

 

 

三.Android中Service多线程操作运行耗时操作。

    一下演示Android服务如何在多线程下进行耗时操作。

1.创建ManyThreadService.java 服务

public class ManyThreadService extends Service
{

    private static final String TAG = "ManyThreadService";

    @Override
    public IBinder onBind(Intent intent)
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate()
    {    
        Log.i(TAG, "ManyThreadService==>>onCreate==>线程ID:"+Thread.currentThread().getId());
    
    }
    private class MyThread extends Thread
    {

        @Override
        public void run()
        {
            
            try
            {
                Log.i(TAG, "ManyThreadService==>>文件下载线程ID:"+Thread.currentThread().getId());
                Log.i(TAG, "文件下载中。。。。。>>文件现在线程ID:"+Thread.currentThread().getId());
                Thread.sleep(5000);
                Log.i(TAG, "文件现在完成。 >>文件下线线程ID:"+Thread.currentThread().getId());
            } catch (InterruptedException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        
        Log.i(TAG, "ManyThreadService==>>onStartCommand中开启线程==>线程ID"+Thread.currentThread().getId());
        new MyThread().start();
        return START_STICKY;
    }
    @Override
    public void onDestroy()
    {
        Log.i(TAG, "ManyThreadService==>>onDestory==>线程ID"+Thread.currentThread().getId());
        super.onDestroy();
    }
    

}

2.创建新线程进行耗时操作:

private class MyThread extends Thread
    {

        @Override
        public void run()
        {
            
            try
            {
                Log.i(TAG, "ManyThreadService==>>文件下载线程ID:"+Thread.currentThread().getId());
                Log.i(TAG, "文件下载中。。。。。>>文件现在线程ID:"+Thread.currentThread().getId());
                Thread.sleep(5000);
                Log.i(TAG, "文件现在完成。 >>文件下线线程ID:"+Thread.currentThread().getId());
            } catch (InterruptedException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        
    }

3.开启新线程:

public int onStartCommand(Intent intent, int flags, int startId)
    {
        
        Log.i(TAG, "ManyThreadService==>>onStartCommand中开启线程==>线程ID"+Thread.currentThread().getId());
        new MyThread().start();
        return START_STICKY;
    }

运行效果:从下图看出出,多线程并行操作,提高执行的效率。如果要在Android服务中执行耗时的并行操作服务,适应多线程操作时不错的选择。

如果只是运行异步请求操作 IntentService是不错的选择。

 

 

三.Android中IntentSevice操作。

      IntentService是Service类的子类,用来处理异步请求。客户端通过startService(Intent)方法传递请求给IntentService,

 IntentService通过worker thread处理每个Intent对象,执行完所有工作后自动停止Service。

 写构造方法 复写onHandleIntent()方法

IntentService执行如下操作 

   1.创建一个与应用程序主线程分开worker thread用来处理所有通过传递过来的Intent请求

   2.创建一个work queue,一次只传递一个intent到onHandleIntent()方法中,从而不用担心多线程带来的问题

   3.当处理完所有请求后自动停止服务,而不需要我们自己调用stopSelf()方法

   4.默认实现了onBind()方法,返回值为null

   5. 默认实现了onStartCommand()方法,这个方法将会把我们的intent放到work queue中,然后在onHandleIntent()中执行。

创建 MyIntentService.java 继承:android.app.IntentService

public class MyIntentService extends IntentService
{

    private static final String TAG = "MyIntentService";
    public MyIntentService()
    {
        super("MyIntentService");
    }
    @Override
    public IBinder onBind(Intent intent)
    {
        return null;
    }
    @Override
    public void onCreate()
    {
         Log.i(TAG, "MyIntentService==>>onCreate==>>线程ID:"+Thread.currentThread().getId());
        super.onCreate();
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
         Log.i(TAG, "MyIntentService==>>onStartCommand==>>线程ID:"+Thread.currentThread().getId());
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    protected void onHandleIntent(Intent intent)
    {
        
        try
        {
            Log.i(TAG, "MyIntentService==>>onHandleIntent==>>线程ID:"+Thread.currentThread().getId());
            Log.i(TAG, "文件下载中。。。。。>>文件下载线程ID:"+Thread.currentThread().getId());
            Thread.sleep(5000);
            Log.i(TAG, "文件现在完成>>文件下载线程ID:"+Thread.currentThread().getId());
        } catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        

    }
    @Override
    public void onDestroy()
    {
         Log.i(TAG, "MyIntentService==>>onDestory==>>线程ID:"+Thread.currentThread().getId());
        super.onDestroy();
    }

}

运行效果:从下图可以看出,在每次开启服务时传过去的inent,耗时操作都是有一个线程来执行处理。而所有操作排列成一个线程队列,先执行完个操作,紧接着

执行下一个操作。执行完所以操作后 服务会自动onDestory操作进行销毁。

本写的这里,有些问题是我通过实验总结出来的,有错误的地方请指出来。错误的地方希望大家指出。谢谢。

 

 

posted @ 2013-12-17 22:44    阅读(7526)  评论(0编辑  收藏  举报