Android Service 后台服务之本地服务
2016-05-07 15:53
676 查看
Service是Android系统的服务组件,适用于开发没有用户界面且长时间在后台运行的功能
-
下面我将Service基础知识简单归纳为以下6点:
- 1.Service适用于什么功能?
- 2.Service的特点
- 3.Service的用处
- 4.Service的生命周期
- 5.通过启动方式使用Service
实现
特点
- 6.通过绑定方式使用Service
实现
特点
以下为一个设计到本地服务的简单Demo,包括启动方式和绑定方式的使用。主界面如图:
项目结构如图:
RandomService.java(启动方式)完整代码:
MathService.java(绑定方式)完整代码:
MainActivity.java完整代码:
-
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的生命周期
完整的生命周期从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,包括启动方式和绑定方式的使用。主界面如图:
项目结构如图:
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; } }; }
相关文章推荐
- 嗯,google似乎也会有明显的小bug -- android 模拟器无法ping通主机
- Android getScrollX()详解
- android 学习笔记10——XML解析
- Android之json解析(FastJson Gson 对比)
- Android端上传文件到Web服务器
- 科大讯飞语音接入(AndroidStudio)
- android检测某个服务是否开启
- [Android TV 按键响应]listview的textview跑马灯在鼠标控制下失效的问题
- android databinding之include
- String 与 intern理解
- android蓝牙传输文件时的文件格式限制及其解决方法
- android裁剪图片
- 解决android自带蓝牙不能发送接收某些文件类型
- Android——小谈Android 6.0(棉花糖)
- Android 中Canvas的save(),saveLayer()和restore()解析
- Android 图片加载Bitmap OOM错误解决办法
- Android Studio 常用快捷键
- Android二维码生成功能
- Android开发学习之路-图片颜色获取器开发(1)
- [置顶] android框架