一、创建Service

  1.创建一个myService类,来继承Service。重写其中的方法,包括:onCreate(),onStartCommend(),onDestroy(),onBind()方法是自动重载的。

    1.1 onCreate():创建Service的时候调用,只调用一次。

    1.2 onStartCommend():执行Service的时候调用,执行几次,调用几次。

    1.3 onDestroy():在销毁Service的时候调用,只调用一次。

    1.4 onBind():在bindService的时候调用。只调用一次。

  1.2 myService代码如下:

package com.wangpei.service;

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

/**
 * 作者:WangPei on 2015/7/9 09:48
 * 邮箱:460977141@qq.com
 */
public class myService extends Service {

    private static final String TAG = "myInfo";
  //需要返回Binder实例
private MyBinder myBinder = new MyBinder(); @Override public IBinder onBind(Intent intent) { return myBinder; } @Override public void onCreate() { Log.i(TAG,"onCreate is excute"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG,"onStartCommand is excute"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Log.i(TAG,"onDestroy is excute"); super.onDestroy(); } class MyBinder extends Binder{ public void startDownload(){
        //模拟下载任务 Log.i(TAG,
"startDownload is excute"); } } }

 

二、startService AND stopService

  2.1 startService

    2.1.1 代码如下:

Intent startIntent = new Intent(MainActivity.this,myService.class);
                startService(startIntent);

    2.1.2 调用myService类中的方法顺序如下:

        onCreate() ---> onStartCommend() ---先创建Service,然后在执行。

  2.2 stopService 代码如下:

    2.2.1 代码如下:

Intent stopIntent = new Intent(MainActivity.this,myService.class);
                stopService(stopIntent);

    2.2.2 调用myService类中的方法顺序如下:

        onDestroy() --直接被销毁。

三、bindService AND unBindService

  3.1 创建ServiceConnection:

//初始化myService中的binder
private myService.MyBinder myBinder;


private
ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { myBinder = (myService.MyBinder) service;
       //启动下载任务 myBinder.startDownload(); } @Override
public void onServiceDisconnected(ComponentName name) { } };

    3.1.1 onServiceConnected()方法,是在Activity和Service建立连接的时候,进行调用。

    3.1.1 onServiceDisconnected()方法,onServiceDisconnected()方法不是解除关联的时候调用,而是发生异常时调用的。

  3.2 bindService 代码如下:

Intent bindIntent = new Intent(MainActivity.this,myService.class);
                bindService(bindIntent,connection,BIND_AUTO_CREATE);

    3.2.1 BIND_AUTO_CREATE:意思是在绑定Service的时候,进行自动创建。

  3.3 unBindService 代码如下:

unbindService(connection);

  3.4 注意 如果同时startService和bindService,必须要stopService和unBindService,才能onDestroy()该Service。

   3.5 额外的东西

    楼主文中是有说明Service和Activity是如何通信的;首先在自定义的Service类中覆盖onBind(Intent intent)方法,返回一个Binder子类的对象,在自定义的Binder子类中可以定义一些方法;然后再Activity创建个ServiceConnection对象,并实现其onServiceConnected(ComponentName name, IBinder service) 方法,在这个方法中将传入的IBinder对象强转为在Service中定义的Binder子类,这样就拿到了Service中的某个对象的引用了,想怎通信都行;但要使onServiceConnected方法被回调,还需要调用bindService方法,把ServiceConnection的对象当作参数传过去......

四、Service AND Thread 的关系

  4.1 Service

    4.1.1 Service旨在后台运行,并且Service也是在主线程中运行的。

    4.1.2 Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。

    4.1.3 使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。

    4.1.4 我们可以在Service中再创建一个子线程,然后在这里去处理耗时逻辑就没问题了。

    4.1.5 较为标准的Service写法:

 

private MyBinder myBinder;


@Override  
public Binder onBind(Intent intent){
  return myBinder;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) { new Thread(new Runnable() { @Override public void run() { // 开始执行后台任务 } }).start(); return super.onStartCommand(intent, flags, startId); } class MyBinder extends Binder { public void startDownload() { new Thread(new Runnable() { @Override public void run() { // 执行具体的下载任务 } }).start(); } }

  4.2 Thread

    4.2.1 Thread是在子线程中运行的,旨在不影响主线程的运行。

           4.2.2 Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例;

五、前台Service

  5.1 需要在通知栏显示,点击之后,可以跳转到Activity。优点,可以保持持续的运行。比如说墨迹天气,它的Service在后台更新天气数据的同时,还会在系统状态栏一直显示当前天气的信息。具体实现如下:

 

public class MyService extends Service {  
  
    public static final String TAG = "MyService";  
  
    private MyBinder mBinder = new MyBinder();  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
    //先定义通知 Notification notification
= new Notification(R.drawable.ic_launcher, "有通知到来", System.currentTimeMillis());
    //跳转意图 Intent notificationIntent
= new Intent(this, MainActivity.class);
    //将意图转换为等待意图 PendingIntent pendingIntent
= PendingIntent.getActivity(this, 0, notificationIntent, 0);
    //初始化通知 notification.setLatestEventInfo(
this, "这是通知的标题", "这是通知的内容", pendingIntent);
    //然后调用startForeground()方法就可以让MyService变成一个前台Service,并会将通知的图片显示出来。 startForeground(
1, notification); Log.d(TAG, "onCreate() executed"); } ......... }

 六、远程Service

  6.1 远程Service介绍:

        在注册service的时候,添加属性:remote即可激活远程service。远程service,是不同有主进程的service。直接可以在内部执行耗时操作,并且不影响主进程的使用。但是,有一个弊端。远程service没有办法和Activity进行绑定。因为,远程service是不同于应用程序主进程的进程,他们之间无法建立连接的。

     那么如何,才能使Activity和远程service建立连接呢?这里我们需要使用AIDL。接口定义语言来实现跨进程通信技术。

  6.2 AIDL(android interface definition language)的使用:

    6.2.1 使用方法,先建立一个后缀为AIDL的文件,这是一个接口文件。然后进行编译。系统会自动生成一个java文件。然后我们就可以进行使用了。

// IMyAidlInterface.aidl
package com.wangpei.service;

// Declare any non-default types here with import statements

interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
   int plus(int a, int b);
   String toUpperCase(String str);
}

   6.2.2 然后进行编译,系统会自动生成一个相应的java文件。此时,我们就可以使用它了。

在MyService中进行使用(对aidl中的方法,进行重写。):

package com.wangpei.service;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

/**
 * 作者:WangPei on 2015/7/9 09:48
 * 邮箱:460977141@qq.com
 */
public class myService extends Service {

    private static final String TAG = "myInfo";
    private MyBinder myBinder = new MyBinder();

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

    IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {
        @Override
        public int plus(int a, int b) throws RemoteException {
            return a+b;
        }

        @Override
        public String toUpperCase(String str) throws RemoteException {
            if(str != null){

            return str.toUpperCase();
            }else {
                return null;
            }
        }
    };


    @Override
    public void onCreate() {
        Log.i(TAG,"onCreate is excute");
//        Log.i(TAG,"myService thread is :"+Thread.currentThread().getName());



        /**
         * 前台Service的使用
         */
//        Notification notification = new Notification(R.drawable.ic_launcher,"这是通知的内容",System.currentTimeMillis());
//        Intent notificationIntent = new Intent(this,MainActivity.class);
//        PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);
//        notification.setLatestEventInfo(this,"这是通知的标题","这是主要内容",pendingIntent);
//        startForeground(1,notification);

        super.onCreate();
    }

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

    @Override
    public void onDestroy() {
        Log.i(TAG,"onDestroy is excute");
        super.onDestroy();
    }

    class  MyBinder extends Binder{

        public void startDownload(){
            Log.i(TAG,"startDownload is excute");
        }
    }
}

  6.2.3 最后在Activity中进行调用,即可,使用Aidl中,所定义的方法。

 private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
//            myBinder = (myService.MyBinder) service;
//            myBinder.startDownload();
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
            try {
                int result = iMyAidlInterface.plus(9,15);
                String str = iMyAidlInterface.toUpperCase("wang pei");

                Log.i(TAG,result+"");
                Log.i(TAG,str);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }