什么是服务?
服务(service)是Android中实现程序后台运行的解决方案,适用于去执行那些不需要和用户交互并且还需要长期运行的任务。服务的运行不依赖于任何用户界面。
服务运行在主线程中,所以在service不能用来做一些耗时操作。
服务的用法
1.新建一个继承自Service的类,并实现其抽象方法
2.构建一个Intent
3.使用startService(intent)启动服务
4.使用stopService(intent)停止服务
服务在创建的时候会调用其onCreate()方法,而在每次启动服务的时候都会调用onStartCommand()方法,在服务销毁的时候会调用onDestroy()方法。
Service和Activity的通信
在现实编程中,我们除了要开启关闭Service之外,我们往往还需要获取Service执行的步骤、进度等等,这就需要Service和Activity之间进行通信。
想要Activity和Service之间进行通信,需要使用bindService()和unbindService()方法启动、关闭Service。
bindService()方法有三个参数,分别是:
1.service:通过Intent指定要启动的Service
2.conn:一个ServiceConnection对象,该对用用于监听访问者与Service之间的连接情况。当访问者与Service之间连接成功时将回调该ServiceConnection的onServiceConnectioned方法,当Service所在的宿主进程终止,导致Service与访问者之间断开连接的时回调该ServiceConnection的onServiceDesconnected方法
3.flags:指定绑定时是否自动创建Service(如果该Service还没有创建)。可指定为0(不自动创建),BIND_AUTO_CREATE(自动创建)。
Activity传值给Service
MainActivity.java
package com.example.servicedemo; import com.example.servicedemo.MyService.MyBinder; 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.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener { private Button start_service_button, stop_service_button, bind_service_button, unbind_service_button, pass_on_message; private TextView tvOut; private Intent intent; private MyBinder myBinder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); start_service_button = (Button) findViewById(R.id.start_service_button); stop_service_button = (Button) findViewById(R.id.stop_service_button); bind_service_button = (Button) findViewById(R.id.bind_service_button); unbind_service_button = (Button) findViewById(R.id.unbind_service_button); pass_on_message = (Button) findViewById(R.id.pass_on_message); tvOut = (TextView) findViewById(R.id.tvOut); start_service_button.setOnClickListener(this); stop_service_button.setOnClickListener(this); bind_service_button.setOnClickListener(this); unbind_service_button.setOnClickListener(this); pass_on_message.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.start_service_button: start(); break; case R.id.stop_service_button: stop(); break; case R.id.bind_service_button: bind(); break; case R.id.unbind_service_button: unbind(); break; case R.id.pass_on_message: passOnMessage(); break; } } // 传递数据 private void passOnMessage() { myBinder.setData("BBBBB"); } // 解除绑定Service private void unbind() { Intent intent = new Intent(this, MyService.class); Log.d("TTTT", "===========点击了unbind按钮============"); unbindService(conn); } // 绑定启动service private void bind() { Intent intent = new Intent(this, MyService.class); Log.d("TTTT", "===========点击了bind按钮============"); bindService(intent, conn, BIND_AUTO_CREATE); } // 使用stopService关闭Service private void stop() { Intent intent = new Intent(this, MyService.class); Log.d("TTTT", "===========点击了stop按钮============"); stopService(intent); } // 使用startService启动Service private void start() { Intent intent = new Intent(this, MyService.class); Log.d("TTTT", "===========点击了start按钮============"); startService(intent); } ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub } @Override public void onServiceConnected(ComponentName name, IBinder service) { myBinder = (MyBinder) service; } }; }
MyService.java
package com.example.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 String data = "AAAAA"; @Override public IBinder onBind(Intent intent) { Log.d("TTTT", "IBind方法运行了..."); return new MyBinder(); } @Override public void onCreate() { Log.d("TTTT", "onCreate方法运行了..."); new Thread(new Runnable() { @Override public void run() { int j = 0; for (int i = 0; i < 30; i++) { try { j++; String str = j + ":" + data; Log.d("TTTT", str); Thread.sleep(1000 * 1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }).start(); super.onCreate(); } @Override public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub super.onStart(intent, startId); Log.d("TTTT", "onStart方法运行了..."); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("TTTT", "onStartCommand方法运行了..."); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d("TTTT", "onDestroy方法运行了..."); } @Override public boolean onUnbind(Intent intent) { Log.d("TTTT", "onUnbind方法运行了..."); return super.onUnbind(intent); } public class MyBinder extends Binder { public void setData(String str) { data = str; } public MyService getService() { return MyService.this; } } }
activity_main.xml
<LinearLayout 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" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.servicedemo.MainActivity" > <TextView android:id="@+id/tvOut" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/start_service_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开启服务" /> <Button android:id="@+id/stop_service_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="关闭服务" /> <Button android:id="@+id/bind_service_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="绑定服务" /> <Button android:id="@+id/unbind_service_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="解除绑定" /> <Button android:id="@+id/pass_on_message" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="传递数据" /> </LinearLayout>
Service传值给Activity
MainActivity.java
package com.example.passupmessageforservice; import com.example.passupmessageforservice.MyService.Callback; import com.example.passupmessageforservice.MyService.MyBinder; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener { private Button bt_bindService, bt_unbindService, bt_sync; private TextView showtext; private EditText et_str; private Intent intent; private MyBinder myBinder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); bt_bindService.setOnClickListener(this); bt_unbindService.setOnClickListener(this); bt_sync.setOnClickListener(this); } // 初始化view组件 private void initView() { bt_bindService = (Button) findViewById(R.id.bt_bindService); bt_unbindService = (Button) findViewById(R.id.bt_unbindService); bt_sync = (Button) findViewById(R.id.bt_sync); showtext = (TextView) findViewById(R.id.showtext); et_str = (EditText) findViewById(R.id.et_str); } // 响应点击事件 @Override public void onClick(View v) { switch (v.getId()) { case R.id.bt_bindService: bind(); break; case R.id.bt_unbindService: unbind(); break; case R.id.bt_sync: sync(); break; } } // 绑定服务 private void bind() { Log.d("TTTT", "=========执行bind方法========="); intent = new Intent(this, MyService.class); bindService(intent, conn, BIND_AUTO_CREATE); } // 解除绑定 private void unbind() { Log.d("TTTT", "=========执行unbind方法========="); unbindService(conn); } // 同步数据方法 private void sync() { myBinder.setData(et_str.getText().toString()); } ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { Log.d("TTTT", "=========执行onServiceDisconnected方法========="); } @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.d("TTTT", "=========执行onServiceConnected方法========="); myBinder = (MyBinder) service; myBinder.getService().setCallback(new Callback() { public void change(String str) { Log.d("TTTT", "~~~~~"); Message msg = new Message(); msg.obj = str; handler.sendMessage(msg); } }); } }; Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { String str = (String) msg.obj; showtext.setText(str); }; }; }
MyService.java
package com.example.passupmessageforservice; 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 String logStr = "AAAA"; private Callback callback = null; private boolean status = false; @Override public IBinder onBind(Intent intent) { Log.d("TTTT", "~~~~~~~~~~~~执行onBind方法~~~~~~~~~~~~"); return new MyBinder(); } @Override public boolean onUnbind(Intent intent) { Log.d("TTTT", "~~~~~~~~~~~~执行onUnbind方法~~~~~~~~~~~~"); status = true; return super.onUnbind(intent); } @Override public void onCreate() { super.onCreate(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 15; i++) { if (!status) { if (callback != null) { callback.change(i + ":" + logStr); Log.d("TTTT", "================================"); } try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }).start(); Log.d("TTTT", "~~~~~~~~~~~~执行onCreate方法~~~~~~~~~~~~"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("TTTT", "~~~~~~~~~~~~执行onStartCommand方法~~~~~~~~~~~~"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Log.d("TTTT", "~~~~~~~~~~~~执行onDestroy方法~~~~~~~~~~~~"); super.onDestroy(); } public class MyBinder extends Binder { public void setData(String str) { logStr = str; } public MyService getService() { return MyService.this; } } public interface Callback { void change(String str); } public Callback getCallback() { return callback; } public void setCallback(Callback callback) { this.callback = callback; } }
activity_main.xml
<LinearLayout 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" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.passupmessageforservice.MainActivity" > <EditText android:id="@+id/et_str" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="输入要传入的文字" /> <Button android:id="@+id/bt_bindService" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="绑定服务" /> <Button android:id="@+id/bt_unbindService" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="解除绑定" /> <Button android:id="@+id/bt_sync" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="同步数据" /> <TextView android:id="@+id/showtext" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
Service的生命周期
Service的生命周期,从创建到销毁,有两条不同的路径。
直接启动
使用startService()启动Service,初次启动会先调用onCreate()方法,然后调用onStartCommand()方法,创建Service之后,之后不会再调用onCreate()方法
这种Service可以无限的运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它
停止时会调用其onDestroy()方法来销毁这个Service
绑定启动
被绑定的Service是当其他组件调用bindService来创建的
初次绑定会调用onCreate()方法,之后便不会再调用
紧接着会调用onBind()方法
当别的组件调用unbindService()时候,会调用Service的unbind方法,紧接着调用onDestroy()方法。