首页 > 代码库 > Service和Activity之间的通信
Service和Activity之间的通信
Service的启动方式有两种,一种是通过start方式,一种是通过bind方式,通过start方式启动服务后,启动服务的组件和服务便没有多大联系了。所以为了能和Service通信,只能通过bind的方式。下面分几步介绍下:(demo里面的Service提供一个下载的功能,然后在Activity中决定何时开始下载,以及随时查看下载进度)
第一步:
在Service类中创建一个内部类继承自Binder(onBind方法返回IBinder接口,Binder类是IBinder接口的实现类)(看到这里还实现了一个接口,并实现了接口里的方法,还提供了一个额外的方法,这个额外的方法不希望Activity访问到,所以这里我们通过接口的方式):
//1. private class DownloadBinder extends Binder implements DownloadBinderImpl{ @Override public void startDownload() { Log.i(TAG, "startDownload"); } @Override public int getProgress() { Log.i(TAG, "getProgress"); return 0; } public void Inner(){ Log.i(TAG, "我不希望Activity使用我"); } }第二步:上面提到的接口:
package com.dystu.servicedemo; public interface DownloadBinderImpl { public void startDownload(); public int getProgress(); }
第三步:在Service的onBind()方法里面返回DownloadBinder实例:
@Override public IBinder onBind(Intent intent) { Log.i(TAG, "onBind"); return new DownloadBinder(); }
第四步:在Activity中绑定服务:
public void bind(View view) { Intent intent = new Intent(this, MyService.class); bindService(intent, conn, BIND_AUTO_CREATE); }第五步:创建ServiceConnection 匿名内部类,实现了onServiceConnected和onServiceDisconnected方法,这两个方法会在服务成功绑定和解除绑定的时候调用。
private class MyConn implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { dbi = (DownloadBinderImpl) service; Log.i(TAG, "成功绑定服务----onServiceConnected执行了"); } @Override public void onServiceDisconnected(ComponentName name) { Log.i(TAG, "解除绑定服务----onServiceDisconnected执行了"); } }
第六步:
调用服务的方法:
public void call(View view) { if (dbi != null) { dbi.startDownload(); dbi.getProgress(); } else { Toast.makeText(this, "请先绑定服务", 0).show(); } }
也可在onServiceConnected中执行。
实现的效果:
点击bind:
点击call:
点击unbind:
完整的代码:
接口:
package com.dystu.servicedemo; public interface DownloadBinderImpl { public void startDownload(); public int getProgress(); }
服务:
package com.dystu.servicedemo; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class MyService extends Service { private static final String TAG = "MyService"; // 2. @Override public IBinder onBind(Intent intent) { Log.i(TAG, "onBind"); return new DownloadBinder(); } @Override public boolean onUnbind(Intent intent) { Log.i(TAG, "onUnbind"); return super.onUnbind(intent); } @Override public void onCreate() { super.onCreate(); Log.i(TAG, "onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.i(TAG, "onDestroy"); } //1. private class DownloadBinder extends Binder implements DownloadBinderImpl{ @Override public void startDownload() { Log.i(TAG, "startDownload"); } @Override public int getProgress() { Log.i(TAG, "getProgress"); return 0; } public void Inner(){ Log.i(TAG, "我不希望Activity使用我"); } } }
主界面布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="${relativePackage}.${activityClass}" > <Button android:id="@+id/btn1" android:onClick="bind" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="bind" /> <Button android:id="@+id/btn2" android:layout_below="@id/btn1" android:onClick="unbind" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="unbind" /> <Button android:layout_below="@id/btn2" android:onClick="call" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="call" /> </RelativeLayout>
MainActivity:
package com.dystu.servicedemo; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.View; import android.widget.Toast; public class MainActivity extends Activity { public static final String TAG = "MainActivity"; private MyConn conn; DownloadBinderImpl dbi; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); conn = new MyConn(); } // 3. public void bind(View view) { Intent intent = new Intent(this, MyService.class); bindService(intent, conn, BIND_AUTO_CREATE); } public void unbind(View view) { unbindService(conn); dbi = null; } public void call(View view) { if (dbi != null) { dbi.startDownload(); dbi.getProgress(); } else { Toast.makeText(this, "请先绑定服务", 0).show(); } } // 4. private class MyConn implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { dbi = (DownloadBinderImpl) service; Log.i(TAG, "成功绑定服务----onServiceConnected执行了"); } @Override public void onServiceDisconnected(ComponentName name) { Log.i(TAG, "解除绑定服务----onServiceDisconnected执行了"); } } }
PS:
类ServiceConnection中的onServiceDisconnected()方法在正常情况下是不被调用的,它的调用时机是当Service服务被异外销毁时,例如内存的资源不足时这个方法才被自动调用。
Service和Activity之间的通信
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。