Android Service 后台服务之本地服务

Service是Android系统的服务组件,适用于开发没有用户界面且长时间在后台运行的功能

    -

Service简介

因为手机硬件性能和屏幕尺寸的限制,通常Android系统仅允许一个应用程序处于激活状态并显示在手机屏幕上,而暂停其他处于未激活状态的程序。
因此,Android系统需要一种后台服务机制,允许在没有用户界面的情况下,使程序能够长时间在后台运行,实现应用程序的后台服务功能。

在实际应用中,有很多应用需要使用Service,比如MP3播放器要求在关闭播放器界面后,仍然能够后台保持音乐持续播放。 

下面我将Service基础知识简单归纳为以下6点:

- 1.Service适用于什么功能?

Service使用于无须用户干预,且有规则地运行或长期运行的后台共功能。

- 2.Service的特点

Service没有用户界面,相比于其他应用程序更加有利于降低系统资源的消耗。

Service比Activity具有更高优先级,在资源紧张时,Service不会被Android系统优先终止。

即使Service被系统终止,在系统资源恢复后Service也将自动回复运行状态,因此可以认为Service是在系统中可以稳定长期运行的组件。

- 3.Service的用处

1.实现后台服务功能

2.可用于进程间通信

- 4.Service的生命周期

Service的生命周期

完整的生命周期从onCreate()开始到onDestroy()结束,在onCreate()中完成Service的初始化工作,在onDestroy()中释放所有占用的资源。
可以粗略的认为活动生命周期以onDestroy()标志结束。

- 5.通过启动方式使用Service

  • 实现

    通过Context.startService()启动Service,通过Context.stopService()停止Seivice。
    Context指其他组件,因此Service一定是由其它组件启动的,但停止过程可以通过其他组件或自身完成。
    
  • 特点

    启动Service的组件无法获取Service的对象实例,因此也无法调用Service中的任何函数,
    也不能获取Service中的任何状态和数据信息。所以以启动方式的Service需要具备自管理的能力。
    

- 6.通过绑定方式使用Service

  • 实现

    在其他组件中调用Context.bindService()建立服务连接,调用Context.unbindService()停止服务连接。
    如果在绑定过程中Service未启动,Context.bindService()会自动启动Service。
    
  • 特点

    其他组件可以获取Service的实例对象并调用Service中的函数,可以获取Service中的状态和数据信息。
    同一个Service可以和被多个组件绑定服务连接,即同一个Service可以同时为多个组件服务。
    

本地服务

概念: 本地服务的调用者和服务都在同一个程序中,是不需要跨进程就可以实现服务的调用。
以下为一个设计到本地服务的简单Demo,包括启动方式和绑定方式的使用。主界面如图:
Android Service 后台服务之本地服务_第1张图片

项目结构如图:
Android Service 后台服务之本地服务_第2张图片

RandomService.java(启动方式)完整代码:

package com.example.servicedemo;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;

/** * Created by yinghao on 2016/5/6. */
public class RandomService extends Service {

    /* onStartCommand 取代 onStart 但在 super.onStartCommand(intent, flags, startId); 方法中调用了 onStart()方法(为了兼容) */

    private Thread workThread;
    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, "调用onCreate()", Toast.LENGTH_SHORT).show();
        workThread = new Thread(null, backgroundWork, "workThread");
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Toast.makeText(RandomService.this, "onStart()", Toast.LENGTH_SHORT).show();
        if (!workThread.isAlive()) {
            workThread.start();
        }

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(RandomService.this, "onStartCommand()", Toast.LENGTH_SHORT).show();

        return super.onStartCommand(intent, flags, startId);


    }

    @Override
    public void onDestroy() {
        Toast.makeText(this, "调用onDestroy()", Toast.LENGTH_SHORT).show();
        workThread.interrupt();
        super.onDestroy();

    }

    private Runnable backgroundWork = new Runnable() {
        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    double randomDouble = Math.random();
                    MainActivity.UpdateGUI(randomDouble);

                    Thread.sleep(1000);

                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };





    /** * Service 被绑定后调用的函数,能够返回Service对象实例 */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

MathService.java(绑定方式)完整代码:

package com.example.servicedemo;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;

/** * Created by yinghao on 2016/5/6. */
public class MathService extends Service {

    /** * 以绑定形式使用此Service 获取Service实例 */
    private final IBinder mBinder = new LocalBinder();
    public class LocalBinder extends Binder{
        MathService getService() {
            return MathService.this;
        }
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(MathService.this, "本地绑定", Toast.LENGTH_SHORT).show();
        return mBinder;
    }


    @Override
    public boolean onUnbind(Intent intent) {
        Toast.makeText(MathService.this, "取消本地绑定:MathService", Toast.LENGTH_SHORT).show();
        return super.onUnbind(intent);
    }

    public long add(long a, long b) {
        return a + b;
    }
}

MainActivity.java完整代码:

package com.example.servicedemo;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.example.simplerandomservicedemo.R;

public class MainActivity extends AppCompatActivity {

    private Button mStartButton;
    private Button mStopButton;
    private static TextView mLabelTextVie;
    private static Handler handler = new Handler();
    private static double random;
    /** * Handler 将Runnable对象 传递给 界面线程的队列中 * 使其能更新UI */
    public static void UpdateGUI(double refreshDouble) {
        random = refreshDouble;
        handler.post(RefreshLable);
    }
    public static Runnable RefreshLable = new Runnable() {
        @Override
        public void run() {
            mLabelTextVie.setText(String.valueOf(random));
        }
    };


    private MathService mathService;
    private boolean isBound = false;
    private TextView sum;
    private Button bindButton;
    private Button unbindButton;
    private Button addButton;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /** * Handler */
        final Intent intent = new Intent(this,RandomService.class);
        mStartButton = (Button) findViewById(R.id.start);
        mStopButton = (Button) findViewById(R.id.stop);
        mLabelTextVie = (TextView) findViewById(R.id.tv_label);
        mStartButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startService(intent);

            }
        });
        mStopButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopService(intent);
            }
        });
        /** * bind Service */
         sum = (TextView) findViewById(R.id.tv_result);
         bindButton = (Button) findViewById(R.id.bind);
         unbindButton = (Button) findViewById(R.id.unbind);
         addButton = (Button) findViewById(R.id.add);

        final Intent serviceIntent = new Intent(MainActivity.this, MathService.class);

        bindButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!isBound) {
                    bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
                    isBound = true;
                }
            }
        });
        unbindButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isBound) {
                    unbindService(mConnection);
                    //若把上面取消绑定改为下面的关闭Service 则无法再次绑定成功
// stopService(serviceIntent);
                    mathService = null;
                    isBound = false;
                }
            }
        });
        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mathService == null) {
                    sum.setText("未绑定服务");
                    return;
                }
                long a = Math.round(Math.random() * 100);
                long b = Math.round(Math.random() * 100);
                long result = mathService.add(a, b);
                String msg = String.valueOf(a)+"+"+String.valueOf(b)+"="+result;
                sum.setText(msg);

            }
        });

    }
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mathService = ((MathService.LocalBinder) service).getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mathService = null;
        }
    };

}

你可能感兴趣的:(android)