Android Service 与 Activity 通讯
前面几章节 Activity 只是负责启动和停止 Service
,但如果启动的是一个下载
的后台 Service,而我们又想知道 Service 中下载任务的进度,那么就需要 Service
与 Activity 进行通信
Activity 与 Service 通信的媒介就是 Service 中的 onBind()
方法
onBind()
方法会返回一个自定义的 Binder 对象
基本流程如下
-
在自定义 Service 中,自定义一个 Binder 类,然后将需要暴露的方法都写到该类中
-
Service 类中,实例化这个自定义 Binder 类,然后重写
onBind()
方法,返回这个 Binder 对象 -
Activity 类中实例化一个
ServiceConnection
对象,重写onServiceConnected()
方法,获取 Binder 对象,调用相关方法
范例
我们写一个前台服务来演示下上面的流程
注意
Service 一般都是运行在后来的,但是 Service的系统优先级还是比较低的,当系统内存不足的时候,就有可能回收正在后台运行的 Service, 对于这种情况我们可以使用前台服务,从而让 Service 稍微没那么容易被系统杀死, 当然还是有可能被杀死的
所谓的前台服务就是状态栏显示的 Notification
在自定义的 Service 类中,重写 onCreate(),然后根据自己的需求定制 Notification
定制完毕后,调用 startForeground(1,notification对象)
先来看看最后的效果图
-
创建一个 空的 Android 项目
cn.twle.android.ServiceActivity
-
在
MainActivity.java
同一目录下新建文件MsTestService.java
package cn.twle.android.serviceactivity; import android.app.NotificationManager; import android.app.Service; import android.app.Notification; import android.app.PendingIntent; import android.os.Binder; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; public class MsTestService extends Service { private int count = 0; private MsBinder binder = new MsBinder(); public class MsBinder extends Binder { public int getCount() { return count; } } @Override public void onCreate() { super.onCreate(); Notification.Builder builder = new Notification.Builder(this.getApplicationContext()); builder.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0)); builder.setAutoCancel(false); builder.setSmallIcon(R.mipmap.ic_launcher); builder.setTicker("Foreground Service Start"); builder.setContentTitle("Socket服务端"); builder.setContentText("正在运行..."); // 获取构建好的 Notification Notification notification = builder.build(); notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音 startForeground(110,notification); NotificationManager mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); mNM.notify(1234,notification); } @Override public IBinder onBind(Intent intent) { return binder; } }
-
然后修改
AndroidManifest.xml
文件中注册Service
<service android:name=".MsTestService"> <intent-filter> <action android:name="cn.twle.android.serviceactivity.MsTestService" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service>
-
修改 MainActivity.java
package cn.twle.android.serviceactivity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private MsTestService.MsBinder mBinder; private TestConnection conn = new TestConnection(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent it = new Intent(this,MsTestService.class); bindService(it, conn, BIND_AUTO_CREATE); } private final class TestConnection implements ServiceConnection { public void onServiceConnected(ComponentName name, IBinder service) { mBinder = (MsTestService.MsBinder)service; } public void onServiceDisconnected(ComponentName name) { mBinder = null; } } }