码迷,mamicode.com
首页 > 移动开发 > 详细

Android--服务

时间:2015-09-29 21:46:12      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:

服务

一.基础知识

服务一般分为两种:

1:本地服务, Local Service 用于应用程序内部。

在Service可以调用Context.startService()启动,调用Context.stopService()结束。

在内部可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。无论调用了多少次startService(),都只需调用一次stopService()来停止。

2:远程服务, Remote Service 用于android系统内部的应用程序之间。可以定义接口并把接口暴露出来,以便其他应用进行操作。

调用Context.bindService()方法建立连接,并启动,以调用 Context.unbindService()关闭连接。

多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。

提供给可被其他应用复用,比如定义一个天气预报服务,提供与其他应用调用即可

 

android中服务是运行在后台的东西,级别与activity差不多。既然说service是运行在后台的服务,那么它就是不可见的,没有界面的东西。你可以启动一个服务Service来播放音乐、记录你地理信息位置的改变、启动一个服务来运行并一直监听某种动作。

Service:Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。如:onCreate,onStart 这些函数在被系统调用的时候都是在主进程的 main 线程上运行的。如果是Remote Service,那么对应的 Service 则是运行在独立进程的 main 线程上。因此请不要把 Service 理解成线程,它跟线程半毛钱的关系都没有!

 

onCreate()   创建时候调用,初始化。只在第一次创建的时候执行。

onStartCommand()  启动时候调用,每次启动都会去执行。

onDestory()  销毁时候调用,一般回收那些不再使用的资源。

在XML文件里面注册。

 

startService()  开启服务

stopService()  停止服务

startService() 和 stopService()  方法都定义在Context类中的。所以我们在活动中可以调用这两个方法

这里完全是由活动来决定服务何时停止的(在按钮点击开始服务就开了,点击停止服务就停了)

服务自己停止自己的办法,在MyService()的任何一个位置调用stopSelf()方法就可以让这个服务停下来。

活动和服务之间的通信

虽然服务是在活动里面启动的,但是启动之后,服务就和活动没有关系了。

在活动中指挥服务去做什么,onBind()方法。

public class MyService extends Service {

    private DownloadBinder mBinder = new DownloadBinder();
    
    class DownloadBinder extends Binder{
        //开始下载
        public  void startDownload(){
            Log.d("MyService","startDownload executed");
        }
        //查看下载
        public int getprogress(){
            Log.d("MyService","getProgress executed");
            return 0;
        }
    }
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

 

创建一个专门的Binder对象来对下载功能进行管理。上面活动可以控制服务里面的逻辑。

1、创建了一个DownloadBinder类,继承自Binder,实现了两个模拟方法。

2、创建了DownloadBinder实例,然后在onBinder()方法里面返回这个实例,

绑定服务:活动绑定。,

取消绑定服务:

    private MyService.DownloadBinder downloadBinder;

    private ServiceConnection connection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            downloadBinder = (MyService.DownloadBinder) service;
            downloadBinder.startDownload();
            downloadBinder.getProgress();
        }
    };
  @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.start_service:
            Intent startIntent = new Intent(this, MyService.class);
            startService(startIntent);
            break;
        case R.id.stop_service:
            Intent stopIntent = new Intent(this, MyService.class);
            stopService(stopIntent);
            break;
        case R.id.bind_service:
            Intent bindIntent = new Intent(this, MyService.class);
            bindService(bindIntent, connection, BIND_AUTO_CREATE);
            break;
        case R.id.unbind_service:
            unbindService(connection);
            break;
        case R.id.start_intent_service:
            Log.d("MainActivity", "Thread id is " + Thread.currentThread().getId());
            Intent intentService = new Intent(this, MyIntentService.class);
            startService(intentService);
            break;
        default:
            break;
        }
    }

 

ServiceConnection的匿名类,重写了两个方法,这两个方法分别在活动与服务成功绑定解除绑定的时候调用。

那么如何绑定呢?

bindService(intent,ServiceConnection,标志位)

BIND_AUTO_CREATE 表示活动与服务进行绑定后自动创建服务。会使得onCreat()方法执行,但onStartCommand()方法不会执行。

MyService不仅可以和MainActivity绑定,还可以和任何一个其他的活动进行绑定。

服务的生命周期

            技术分享

当同时调用了startService()和bindService()之后,必须同时调用stopService()和unbindService()方法,onDestory()才会执行。

使用前台服务

前台服务和普通服务最大的区别在于,他会一直有一个正在运行的图标在系统的状态栏显示。

    @Override
    public void onCreate() {
        super.onCreate();
        Notification notification = new Notification(R.drawable.ic_launcher,"Notification comes", System.currentTimeMillis());
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,notificationIntent, 0);
        notification.setLatestEventInfo(this, "This is title", "This is content",pendingIntent);
        startForeground(1, notification);
        Log.d("MyService", "onCreate executed");
    }

 

创建通知。只不过这次创建出的Notification对象并没有使用NotificationManager来将通知显示出来,而是调用了startForeground()方法。

startForeground() 第一个参数是ID,类似于notify()方法的第一个参数,第二个参数则是构建出的Notifacation对象。

调用startForeground() 之后就会让MyService变成一个前台服务。并在系统状态栏显示出来。

使用IntentService

服务中的代码都是运行在主线程中的,如果直接在服务里去处理一些耗时操作,容易出现ANR情况。

所以这个时候就需要用到Android多线程编程的技术了,在服务中开启一个子线程。

记得开启一个线程,并且关闭这个线程,stopSelf()。

IntentService很好的解决了上面两个问题。

public class MyIntentService extends IntentService {

    /**
     * Creates an IntentService.  Invoked by your subclass‘s constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public MyIntentService(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

    }
}

 

必须要提供一个无参的构造函数,并且必须在其内部调用父类的有参构造函数。然后要在子类内去实现onHandlerIntent()这个抽象方法。在这个方法中可以处理一些具体的逻辑。而不用担心ANR的问题。因为这个方法已经在子线程里面执行了,这里为了证实一下,我们在onHandlerIntent()方法中打印了当前线程的ID,另外根据IntentService的特性,这个服务在运行结束后应该会是自动停止的。

 

Android--服务

标签:

原文地址:http://www.cnblogs.com/zrui513/p/4847202.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!