Activity中通过bindService启动Service
2017-11-19 14:24
281 查看
在Activity中,启动Service有两种方式:startService方式,bindService方式。
如果想要调用Service中的方法,只能使用bindService方式。因为这种方式可以拿到Service的Binder对象,从而可以调用Service中的方法。
这里,我们不说怎么调用,只是来验证一个问题:ServiceConnection接口中的onServiceConnected方法执行在哪个线程(另一种问法是:在onServiceConnected方法中是否可以直接更新UI)。
结论:执行在主线程,也就是说,在这个方法中可以直接进行UI更新。
下面,用一个例子来证明上面的结论。
自定义Service类
Service是四大组件之一,记得在清单文件中注册。
Activity类
从打印的日志也可以得到上述结论:
如果想要调用Service中的方法,只能使用bindService方式。因为这种方式可以拿到Service的Binder对象,从而可以调用Service中的方法。
这里,我们不说怎么调用,只是来验证一个问题:ServiceConnection接口中的onServiceConnected方法执行在哪个线程(另一种问法是:在onServiceConnected方法中是否可以直接更新UI)。
结论:执行在主线程,也就是说,在这个方法中可以直接进行UI更新。
下面,用一个例子来证明上面的结论。
自定义Service类
public class SevenService extends Service { private int progress = 0; private OnProgressListener mOnProgressListener; public interface OnProgressListener{ void onProgress(int progress); } public void setOnProgressListener(OnProgressListener listener){ mOnProgressListener = listener; } public class SevenBinder extends Binder { public SevenService getService(){ return SevenService.this; } } public int getProgress(){ return progress; } @Nullable @Override public IBinder onBind(Intent intent) { return new SevenBinder(); } //模拟下载 public void startDownload(){ new Thread(new Runnable() { @Override public void run() { Log.e("startDownload()","Thread: " + Thread.currentThread().getName());//Thread: Thread-9945 while (progress < 100){ progress += 10; //通知调用方 if(null!= mOnProgressListener){ mOnProgressListener.onProgress(progress); } try{ Thread.sleep(1000); }catch (Exception e){ e.printStackTrace(); } } } }).start(); } public void startSetText(){ progress = 19; if(null!= mOnProgressListener){ mOnProgressListener.onProgress(progress); } } }
Service是四大组件之一,记得在清单文件中注册。
Activity类
public class ServiceActivity extends AppCompatActivity { private SevenService mSevenService; private int progress; private TextView service_text; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_service); service_text = (TextView) findViewById(R.id.service_text); Log.e("ServiceActivity","Thread: " + Thread.currentThread().getName());//Thread: main // Intent intent = new Intent(this, SevenService.class); // 标志位BIND_AUTO_CREATE使得服务中onCreate得到执行,onStartCommand不会执行 bindService(intent, conn, Context.BIND_AUTO_CREATE); } //点击按钮 public void bt_download(View view){ // mSevenService.startDownload();//这个方法内部开启了子线程 mSevenService.startSetText(); } /*** * 通过一系列验证,终于确定了:ServiceConnection的onServiceConnected方法是运行在主线程的,可以直接更新UI, */ ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //绑定成功,回调这个方法 mSevenService = ((SevenService.SevenBinder)service).getService(); Log.e("onServiceConnected","Thread: " + Thread.currentThread().getName());//Thread: main mSevenService.setOnProgressListener(new SevenService.OnProgressListener() { @Override public void onProgress(final int progress) { Log.e("setOnProgressListener","Thread: " + Thread.currentThread().getName());//Thread: Thread-9894 //如果点击按钮调用的是startSetText()方法,这里就可以在回调中直接更新UI。 service_text.setText(""+progress); //这里不能直接更新UI的原因是:在SevenService中,startDownload()方法开启了子线程,所以mOnProgressListener.onProgress(progress);是在子线程中执行的 //android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. // runOnUiThread(new Runnable() { // @Override // public void run() { // service_text.setText(""+progress); // } // }); } }); } @Override public void onServiceDisconnected(ComponentName name) { //如果Service中途挂掉,client端也能通过onServiceDisconnected感知到(通过Binder的linkToDeath实现) } }; @Override protected void onDestroy() { unbindService(conn);//解绑 super.onDestroy(); } }
从打印的日志也可以得到上述结论:
相关文章推荐
- Activity通过bindService启动Service后Activity和Service之间的通信!
- Activity通过bindService启动Service后Activity和Service之间的通信!
- Activity通过bindService启动Service后Activity和Service之间的通信!
- Activity通过bindService启动Service后Activity和Service之间的通信!
- android service 通过broadcast通知Myreceiver 启动activity
- 通过bind实现activity与service的交互
- 关于通过bindService启动的service,在unbindService后service是否继续运行的讨论
- 关于通过bindService启动的service,在unbindService后service是否继续运行的讨论
- android开发步步为营之36:四大组件之Service(中)通过bindService启动
- android Service(二) activity启动Service方式二:bindService()
- 1 bindService的启动 2通过AIDL来进行进程间的通信
- 通过action 、filter来启动service/activity
- 关于通过bindService启动的service,在unbindService后service是否继续运行的讨论
- 关于通过adb启动Activity、activity、service以及发送broadcast的命令
- 【Android】Activity切换效果——当通过Service启动自己Activity的时候怎么控制
- 通过bind实现activity与service的交互
- 先startService,通过bindService启动的service,在unbindService后service还会运行
- 通过bindService方法实现Activity与Service的交互
- Android Studio开发基础之启动Service,并通过从Activity向Service传递数据
- 【Android开机启动Activity或者Service方法】