Service 使用方法详解

来源:互联网 发布:开淘宝店运费怎么办 编辑:程序博客网 时间:2024/06/16 02:00

Service 是 Android 四大组件之一(Activity 活动,Service 服务,ContentProvider 内容提供者,BroadcastReceiver 广播),与Activity相比,Activity 是运行在前台,用户可以看得见,Service 则是运行在后台,无用户界面,用户无法看到。Service主要用于组件之间交互(例如:与Activity、ContentProvider、BroadcastReceiver进行交互)、后台执行耗时操作等(例如下载文件,播放音乐等,但Service在主线程运行时长不能超过20s,否则会出现ANR,耗时操作一般建议在子线程中进行操作)。通过本章学习可以基本掌握Service 相关知识点。

​欢迎关注微信公众号:程序员Android
公众号ID:ProgramAndroid
获取更多信息

微信公众号:ProgramAndroid
微信公众号:ProgramAndroid

我们不是牛逼的程序员,我们只是程序开发中的垫脚石。
我们不发送红包,我们只是红包的搬运工。

1.Service 的生命周期
2.四大组件之一,必须在Androidmainfest.xml 中注册
3.启动服务相关知识点
4.绑定服务相关知识点
5.前台服务相关知识点
6.AIDL远程服务相关知识点

Service 继承关系如下:

java.lang.Object   ↳    android.content.Context       ↳    android.content.ContextWrapper           ↳    android.app.Service

1.Service 生命周期

  • 两种 Service 模式 ,对应两种不同生命周期

1.启动服务

通过 startService() 启动,此服务可以在后台一直运行,不随启动组件的消亡而消亡,只能执行单一操作,无法返回结果给调用方。常用于网络下载、上传文件

2.绑定服务

通过绑定组件(Activity等)调用 bindService() 启动,此服务随绑定组件的消亡而解除绑定,如果此时没有其它通过startService()启动,则此服务会随绑定组件的消亡而消亡。多个组件不仅可以同时绑定一个服务,而且可以通过进程间通信(IPC)执行跨进程操作等。

3.两种服务可以同时运行

  只有解除绑定后,才可以销毁服务,否则会引起异常。
  • 两种 Service 模式的生命周期图如下:


    Service 生命周期图
    Service 生命周期图

2.四大组件之一,必须在Androidmainfest.xml 中注册

  • 注册方法如下:
<manifest ... >  ...  <application ... >      <service android:name=".ServiceMethods" />      ...  </application></manifest>

如不注册 不会报异常,但是服务会起不来

3.启动服务

  • 组件启动服务的方法
        Intent  mBindIntent = new Intent(ServiceMethods.this, BindServiceMethods.class);        startService(mStartIntent);
  • 启动服务的生命周期
01-03 17:16:36.147 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onCreate----01-03 17:16:36.223 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onStartCommand----01-03 17:16:38.174 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onDestroy----
  • 启动服务的Demo
    功能:启动服务,在服务中创建通知
package com.android.program.programandroid.component.Service;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.Intent;import android.graphics.BitmapFactory;import android.os.IBinder;import android.support.v4.app.NotificationCompat;import android.util.Log;import com.android.program.programandroid.R;/** * Created by wangjie on 2017/9/7. * please attention weixin get more info * weixin number: ProgramAndroid * 微信公众号: 程序员Android */public class StartServiceMethods extends Service {    private static final String TAG = "StartService wjwj:";    public StartServiceMethods() {    }    @Override    public IBinder onBind(Intent intent) {        // TODO: Return the communication channel to the service.        throw new UnsupportedOperationException("Not yet implemented");    }    @Override    public void onCreate() {        super.onCreate();        Log.i(TAG, "----onCreate----");//        获取NotificationManager实例        NotificationManager notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);//        实例化NotificationCompat.Builder并设置相关属性        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)//                设置小图标                .setSmallIcon(R.mipmap.ic_launcher)                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))//                设置通知标题                .setContentTitle("我是通过StartService服务启动的通知")//                设置通知不能自动取消                .setAutoCancel(false)                .setOngoing(true)//                设置通知时间,默认为系统发出通知的时间,通常不用设置//                .setWhen(System.currentTimeMillis())//               设置通知内容                .setContentText("请使用StopService 方法停止服务");        //通过builder.build()方法生成Notification对象,并发送通知,id=1        notifyManager.notify(1, builder.build());    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.i(TAG, "----onStartCommand----");        return super.onStartCommand(intent, flags, startId);    }    @Override    public void onDestroy() {        Log.i(TAG, "----onDestroy----");        super.onDestroy();    }}

4. 绑定服务

  • 组件启动绑定服务的方法
//    绑定服务连接处理方法    private ServiceConnection serviceConnection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            myBinder=(MyBinder)service;            mBindCount=myBinder.getBindCount();            mUnBindCount=myBinder.getUnBindCount();        }        @Override        public void onServiceDisconnected(ComponentName name) {        }    };//    绑定服务的方法   bindService(mBindIntent, serviceConnection, Context.BIND_AUTO_CREATE);

绑定服务随绑定组件的消亡而消亡

  • 绑定服务的生命周期
01-03 20:32:59.422 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onCreate----01-03 20:32:59.423 13306-13306/com.android.program.programandroid I/BindService wjwj:: -----onBind-----01-03 20:33:09.265 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onUnbind----01-03 20:33:09.266 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onDestroy----
  • 绑定服务Demo
    功能:获取绑定服务及解除绑定服务的次数

  • 绑定服务类

package com.android.program.programandroid.component.Service;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.util.Log;public class BindServiceMethods extends Service {    private static final String TAG = "BindService wjwj:";    public BindServiceMethods() {    }    @Override    public void onCreate() {        super.onCreate();        Log.i(TAG, "----onCreate----");    }    @Override    public IBinder onBind(Intent intent) {        Log.i(TAG, "----onBind----");        MyBinder myBinder = new MyBinder();        return myBinder;    }    @Override    public boolean onUnbind(Intent intent) {        Log.i(TAG, "----onUnbind----");        return super.onUnbind(intent);    }    @Override    public void onDestroy() {        Log.i(TAG, "----onDestroy----");        super.onDestroy();    }}
  • 组件与绑定服务类之间的交互
 //    启动绑定服务处理方法    public void BtnStartBindService(View view) {        bindService(mBindIntent, serviceConnection, Context.BIND_AUTO_CREATE);        isBindService = true;        Toast.makeText(ServiceMethods.this,"启动 "+mBindCount+" 次绑定服务",Toast.LENGTH_SHORT).show();    }    //    解除绑定服务处理方法    public void BtnSopBindService(View view) {        if (isBindService) {            unbindService(serviceConnection);            Toast.makeText(ServiceMethods.this,"解除 "+mUnBindCount+" 次绑定服务",Toast.LENGTH_SHORT).show();            isBindService=false;        }    }
  • 组件之间交互所需的 Binder 接口类
/*** 该类提供 绑定组件与绑定服务提供接口* */public class MyBinder extends Binder {   private int count = 0;    public int getBindCount() {        return ++count;    }    public int getUnBindCount() {        return count> 0 ? count-- : 0;    }}

5. 提高服务的优先级

服务默认启动方式是后台服务,可以通过设置服务为前台服务,提高服务的优先级,进而防止手机内存紧张时,服务进程被杀掉。

注意: 设置前台服务主要使用以下两种方法
// 1.设置为前台服务
startForeground(1, builder.build());
// 2.取消前台服务
stopForeground(true);

  • 前台服务Demo
    功能:前台服务绑定通知信息,提高服务进程优先级,否则取消通知信息
package com.android.program.programandroid.component.Service;import android.app.NotificationManager;import android.app.Service;import android.content.Intent;import android.graphics.BitmapFactory;import android.os.IBinder;import android.support.v4.app.NotificationCompat;import com.android.program.programandroid.R;public class MyStartForcegroundService extends Service {    public MyStartForcegroundService() {    }    @Override    public IBinder onBind(Intent intent) {        // TODO: Return the communication channel to the service.        throw new UnsupportedOperationException("Not yet implemented");    }    @Override    public void onCreate() {        super.onCreate();    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        if (intent.getAction().equals("start_forceground_service")) {//        获取NotificationManager实例            NotificationManager notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);//        实例化NotificationCompat.Builder并设置相关属性            NotificationCompat.Builder builder = new NotificationCompat.Builder(this)//                设置小图标                    .setSmallIcon(R.mipmap.ic_launcher)                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))//                设置通知标题                    .setContentTitle("我是通过startForeground 启动前台服务通知")//                设置通知不能自动取消                    .setAutoCancel(false)                    .setOngoing(true)//                设置通知时间,默认为系统发出通知的时间,通常不用设置//                .setWhen(System.currentTimeMillis())//               设置通知内容                    .setContentText("请使用stopForeground 方法改为后台服务");            //通过builder.build()方法生成Notification对象,并发送通知,id=1//        设置为前台服务            startForeground(1, builder.build());        } else if (intent.getAction().equals("stop_forceground_service")) {                        stopForeground(true);        }        return super.onStartCommand(intent, flags, startId);    }}

6. 使用AIDL接口实现远程绑定

由于内容较多,后续另开一篇详细介绍。

​欢迎关注微信公众号:程序员Android
公众号ID:ProgramAndroid
获取更多信息

微信公众号:ProgramAndroid
微信公众号:ProgramAndroid

我们不是牛逼的程序员,我们只是程序开发中的垫脚石。
我们不发送红包,我们只是红包的搬运工。


点击阅读原文,获取更多福利