欠伸展肢体,吟咏心自愉。这篇文章主要讲述Android—Service与Activity的交互相关的知识,希望能为你提供帮助。
service—android的四大组件之一。人称“后台服务”指其本身的运行并不依赖于用户可视的UI界面
实际开发中我们经常需要service和activity之间可以相互传递数据维持程序的运行。
先了解Service的生命周期吧。
新建一个类继Service:
package com.example.myservicedemo.service; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; /** * 服务类(需要在项目清单文件中注册服务) * * @author lenovo * */ public class MyService extends Service { @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } /** * 服务创建的时候调用 */ @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); System.out.println("=========onCreate======"); } /** * 服务启动的时候调用 */ @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub System.out.println("=========onStartCommand======"); return super.onStartCommand(intent, flags, startId); } /** * 服务销毁的时候调用 */ @Override public void onDestroy() { // TODO Auto-generated method stub System.out.println("=========onDestroy======"); super.onDestroy(); } }
新建以上类并继承Service后只会重写onBind()方法,其他方法是我手动手写,为了弄清楚Service的生命周期
MainActivity中(设置两个按钮用来开始和停止服务):
package com.example.myservicedemo.ui; import com.example.myservicedemo.R; import com.example.myservicedemo.service.MyService; import com.example.myservicedemo.service.MyService.DownLoadBinder; 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.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn_start = (Button) findViewById(R.id.btn_start); Button btn_stop = (Button) findViewById(R.id.btn_stop); btn_start.setOnClickListener(this); btn_stop.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub int id = v.getId(); switch (id) { /* * 开启服务点击事件 */ case R.id.btn_start: Intent startIntent = new Intent(this, MyService.class); startService(startIntent); break; /* * 停止服务点击事件 */ case R.id.btn_stop: Intent stopIntent = new Intent(this, MyService.class); stopService(stopIntent); break; default: break; } }}
切记android中的服务是需要在项目清单文件中注册的(AndroidStudio可以自动,eclipse需要手动添加):
< service android:name="服务类坐所在的包名.MyService"> < /service>
此时运行程序,点击开启服务时候输出是下图:(我输出多次onStartCommand()是因为我连续点击了多次开启服务按钮)
文章图片
上图可以看出服务第一次开启时先是调用了onCreate()方法和onStartCommand()方法,多次点击开始服务时只调用了onStartCommand()方法
so:
onCreate()方法是服务创建的时候调用的~
onStartCommand()方法在每次启动服务的时候都会调用~
onDestory()方法在停止服务时候会调用~
点击停止服务后,输出如图:
文章图片
启动服务还有一种方式是bindService();
此时的MyService类要做改变:
package com.example.myservicedemo.service; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; /** * 服务类(需要在项目清单文件中注册服务) * * @author lenovo * */ public class MyService extends Service { private DownLoadBinder downLoadBinder=new DownLoadBinder(); @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub System.out.println("=====onBind====="); return downLoadBinder; } /** * 内部类继承Binder * @author lenovo * */ public class DownLoadBinder extends Binder{ public void startDownLoad(){ System.out.println("=====startDownLoad()====="); } public void getProgress(){ System.out.println("=====getProgress()====="); } } /** * 服务创建的时候调用 */ @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); System.out.println("=========onCreate======"); } /** * 服务启动的时候调用 */ @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub System.out.println("=========onStartCommand======"); return super.onStartCommand(intent, flags, startId); } /** * 服务销毁的时候调用 */ @Override public void onDestroy() { // TODO Auto-generated method stub System.out.println("=========onDestroy======"); super.onDestroy(); } }
以上的代码和第一次相比,一是多了一个内部类DownLoadBinder继承IBinder并且声明了两个方法,二是将onBind方法的返回值改为了DownLoadBinder类型的变量
activity bindService方法启动服务时候一般是需要传递数据的,核心就在onBind()方法中,往下看
MainActivity中加两个按钮:绑定服务和取消绑定服务
package com.example.myservicedemo.ui; import com.example.myservicedemo.R; import com.example.myservicedemo.service.MyService; import com.example.myservicedemo.service.MyService.DownLoadBinder; 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.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener { private MyService.DownLoadBinder downLoadBinder; private MyService myService; //我们自己的service @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn_start = (Button) findViewById(R.id.btn_start); Button btn_stop = (Button) findViewById(R.id.btn_stop); Button btn_bind = (Button) findViewById(R.id.btn_bind); Button btn_unbind = (Button) findViewById(R.id.btn_unbind); btn_start.setOnClickListener(this); btn_stop.setOnClickListener(this); btn_bind.setOnClickListener(this); btn_unbind.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub int id = v.getId(); switch (id) { /* * 开启服务点击事件 */ case R.id.btn_start: Intent startIntent = new Intent(this, MyService.class); startService(startIntent); break; /* * 停止服务点击事件 */ case R.id.btn_stop: Intent stopIntent = new Intent(this, MyService.class); stopService(stopIntent); break; /* * 绑定服务点击事件 */ case R.id.btn_bind: Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent, connection, BIND_AUTO_CREATE); break; /* * 解除绑定服务点击事件 */ case R.id.btn_unbind: unbindService(connection); break; default: break; } } private ServiceConnection connection=new ServiceConnection() { /** * 服务解除绑定时候调用 */ @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub} /** * 绑定服务的时候调用 */ @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub //myService=((DownLoadBinder) service). downLoadBinder=(DownLoadBinder) service; /* * 调用DownLoadBinder的方法实现参数的传递 */ downLoadBinder.startDownLoad(); downLoadBinder.getProgress(); } }; }
运行后点击绑定服务后输出如下:
文章图片
说明成功绑定了服务且传递了数据,点击解除绑定服务时候ondestory()方法输出
不过这种方法好像只能传递一次数据,,,,不爽,,,,比如后台在实时更新东西,activity需要实时获取呢???
查找资料大多是以下几种方式:
1.使用接口回调方式,activity实现相应的接口,service通过接口进行回调,比较灵活
2.使用广播
这篇博客主要介绍第一种方法,为什么不介绍第二种???——不愿意介绍,不喜欢。
使用接口回调方式的MyService和MainActivity代码我是备注详细之后才粘贴的,大家可以看注释
MyService代码:
package com.example.myservicedemo.service; import java.util.Timer; import java.util.TimerTask; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; /** * 服务类(需要在项目清单文件中注册服务) * * @author lenovo * */ public class MyService extends Service { private DownLoadBinder downLoadBinder=new DownLoadBinder(); /** * 回调 */ private Callback callback; /** * Timer实时更新数据的 */ private Timer mTimer=new Timer(); /** * */ private int num; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub System.out.println("=====onBind====="); return downLoadBinder; } /** * 内部类继承Binder * @author lenovo * */ public class DownLoadBinder extends Binder{ /** * 声明方法返回值是MyService本身 * @return */ public MyService getService() { return MyService.this; } } /** * 服务创建的时候调用 */ @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); /* * 执行Timer 2000毫秒后执行,5000毫秒执行一次 */ mTimer.schedule(task, 0, 1000); } /** * 提供接口回调方法 * @param callback */ public void setCallback(Callback callback) { this.callback = callback; } /** * */ TimerTask task = new TimerTask(){@Override public void run() { // TODO Auto-generated method stub num++; if(callback!=null){ /* * 得到最新数据 */ callback.getNum(num); }} }; /** * 回调接口 * * @author lenovo * */ public static interface Callback { /** * 得到实时更新的数据 * * @return */ void getNum(int num); } /** * 服务销毁的时候调用 */ @Override public void onDestroy() { // TODO Auto-generated method stub System.out.println("=========onDestroy======"); /** * 停止Timer */ mTimer.cancel(); super.onDestroy(); } }
MainActivity代码:
package com.example.myservicedemo.ui; import com.example.myservicedemo.R; import com.example.myservicedemo.service.MyService; import com.example.myservicedemo.service.MyService.Callback; import com.example.myservicedemo.service.MyService.DownLoadBinder; 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.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener { private MyService.DownLoadBinder downLoadBinder; // private MyService myService; //我们自己的service @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn_start = (Button) findViewById(R.id.btn_start); Button btn_stop = (Button) findViewById(R.id.btn_stop); Button btn_bind = (Button) findViewById(R.id.btn_bind); Button btn_unbind = (Button) findViewById(R.id.btn_unbind); btn_start.setOnClickListener(this); btn_stop.setOnClickListener(this); btn_bind.setOnClickListener(this); btn_unbind.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub int id = v.getId(); switch (id) { /* * 开启服务点击事件 */ case R.id.btn_start: Intent startIntent = new Intent(this, MyService.class); startService(startIntent); break; /* * 停止服务点击事件 */ case R.id.btn_stop: Intent stopIntent = new Intent(this, MyService.class); stopService(stopIntent); break; /* * 绑定服务点击事件 */ case R.id.btn_bind: Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent, connection, BIND_AUTO_CREATE); break; /* * 解除绑定服务点击事件 */ case R.id.btn_unbind: unbindService(connection); break; default: break; } } private ServiceConnection connection=new ServiceConnection() { /** * 服务解除绑定时候调用 */ @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub} /** * 绑定服务的时候调用 */ @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub downLoadBinder = (DownLoadBinder) service; MyService service2 = downLoadBinder.getService(); /** * 实现回调,得到实时刷新的数据 */ service2.setCallback(new Callback() {@Override public void getNum(int num) { // TODO Auto-generated method stub System.out.println("====num===="+num); } }); } }; }
运行后的结果应该输出如图就对了(输出随service中num的数量而更新):
文章图片
期间遇到的问题:
bindService后无效,MyService类中的onBind()方法没有被调用
解决:这种情况下你的Activity应该是继承了TabBarActivity,绑定服务的时候调用写这种形式:
this.getApplicationContext().bindService(intent, mConnection, BIND_AUTO_CREATE);
最近几天用到,总结一下,希望可以为大家带来帮助,有错误还请大神指正。
【Android—Service与Activity的交互】
推荐阅读
- 原Android热更新开源项目Tinker源码解析系列之三(so热更新)
- android studio 不能创建或者安装模拟器
- android_m2repository_rxx.zip下载地址以及MD5
- Kotlin的Lambda表达式以及它们怎样简化Android开发(KAD 07)
- Android系统中应用的安装和卸载的监听
- 用Android Studio 出现的问题
- Android自定义View的三种实现方式
- JavaScript中var和let之间有什么区别()
- 算法设计(字符串的不同排列|S2)