Android本地服务
一、服务生命周期总结
(一)、单独开启服务,并没有绑定服务
Activity中调用startService(),服务的lifecycle:onCreate()→onStartCommand()→onStart()
Activity中调用stopService(),服务的lifecycle:onDestroy()
(二)、单独绑定服务,并没有先开启服务
Activity中直接调用bindService(),服务的lifestyle:onCreate()→onBind()
Activity中调用unBindService(),服务的lifecycle:onUnbind()→onDestroy()
(三)、混合使用(先调用开启服务,再调用绑定服务)
1.startService(),服务的lifecycle:onCreate()→onStartCommand()→onStart()
2.bindService(),服务的lifestyle:onBind()
3.unBindService(),服务的lifecycle:onUnbind()
4.stopService(),服务的lifecycle:onDestroy()
(四)、混合使用(先绑定服务,再开启服务。一般不会这么做)
1.bindService(),服务的lifecycle:onCreate()→onBind()
2.startService(),服务的lifestyle:onStartCommand()→onStart()
3.unBindService(),服务的lifecycle:onUnbind()
4.stopService(),服务的lifecycle:onDestroy()
二、Activity与Service交互过程讲解
=============================================================
示例代码
一、布局Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.shz.localservice.MainActivity" tools:ignore="MergeRootFrame" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="bindService" android:text="绑定服务" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="unbindService" android:text="解除绑定服务" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入电影票Id" android:id="@+id/txtTicketId"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="callServiceMethod" android:text="调用服务方法" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/lblTicketInfo" android:textColor="#ff0000"/> </LinearLayout>
二、主要代码
package com.shz.localservice; import java.util.ArrayList; import java.util.List; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; /** * 后台服务(组件),提供查询电影票相关信息 * @author SHZ * */ public class TicketService extends Service { private final static String TAG = "TicketService"; private List<Ticket> tickets; @Override public IBinder onBind(Intent intent) { Log.i(TAG, "onBind 服务绑定成功"); // 2.Activity绑定服务成功之后,服务返回给Activity一个IBinder类型的对象, // 通过该对象,Activity就可以和服务进行交互了,就像一个代理一样 return new TicketBinder(); } @Override public void onCreate() { super.onCreate(); Log.i(TAG, "onCreate 服务创建成功"); this.tickets = new ArrayList<Ticket>(); this.tickets.add(new Ticket(1, "变形金刚4", 103)); this.tickets.add(new Ticket(2, "窃听风云3", 86)); this.tickets.add(new Ticket(3, "反腐风暴", 75)); } @Override public void onStart(Intent intent, int startId) { Log.i(TAG, "onStart 服务启动"); super.onStart(intent, startId); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStartCommand 服务启动"); return super.onStartCommand(intent, flags, startId); } @Override public boolean onUnbind(Intent intent) { Log.i(TAG, "onUnbind 服务解绑成功"); return super.onUnbind(intent); } @Override public void onDestroy() { super.onDestroy(); Log.i(TAG, "onDestroy 服务销毁成功"); } private Ticket getTicket(int id) { for(Ticket ticket:this.tickets) { if(ticket.Id == id) { return ticket; } } return null; } /** * 服务内部方法:查询电影票信息 * @param id * @return */ public String getTicketInfo(int id) { Ticket ticket = this.getTicket(id); if(ticket == null) { return "未查询到该电影票信息"; } else { return ticket.toString(); } } /** * 服务内部方法(测试用,没有意义):更新电影票价格 * @param id * @param newPrice */ public void updateTicketPrice(int id, float newPrice) { Ticket ticket = this.getTicket(id); if(ticket != null) { ticket.Price = newPrice; } } /** * 自定义一个代理类,继承Binder并实现IService接口。 * 服务会返回该类的一个实例给调用者,调用者可通过该实例调用相应的类方法 * @author SHZ * */ private class TicketBinder extends Binder implements IService { /** * 实现IService接口中的方法,调用服务内部的方法,这样调用服务的Activity就可以获取电影票信息了 */ @Override public String getTicketInfoById(int id) { return getTicketInfo(id); } /** * 由于该方法并未在IService接口中定义,故调用者无法使用该方法 * @param id * @param newPrice */ public void updateTicketPrice(int id,float newPrice) { updateTicketPrice(id, newPrice); } } }
package com.shz.localservice; import android.app.Activity; import android.app.ActionBar; import android.app.Fragment; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import android.os.Build; public class MainActivity extends Activity { private TicketServiceConnection conn; private IService ticketBinder; private EditText txtTicketId; private TextView lblTicketInfo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); txtTicketId = (EditText) findViewById(R.id.txtTicketId); lblTicketInfo = (TextView) findViewById(R.id.lblTicketInfo); } private class TicketServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 3.绑定服务成功之后,后台服务会返回IBinder类型的 service 对象,通过该对象可以间接调用后台服务的方法 ticketBinder = (IService) service; } @Override public void onServiceDisconnected(ComponentName name) { } } /** * 开始服务 * @param view */ public void startService(View view) { Intent service = new Intent(this,TicketService.class); startService(service); } /** * 绑定服务 * @param view */ public void bindService(View view) { Intent service = new Intent(this,TicketService.class); // 1.绑定服务 // service:服务意图 // new TicketServiceConnection():与后台服务连接的对象,接收后台服务信息 // BIND_AUTO_CREATE:如果服务没有被创建,则自动创建并绑定 conn = new TicketServiceConnection(); bindService(service, conn, BIND_AUTO_CREATE); } /** * 解除绑定服务 * @param view */ public void unbindService(View view) { unbindService(conn); } /** * 停止服务 * @param view */ public void stopService(View view) { Intent service = new Intent(this,TicketService.class); stopService(service); } @Override protected void onDestroy() { try { unbindService(conn); } catch (Exception e) { } super.onDestroy(); } public void callServiceMethod(View view) { if(this.ticketBinder == null) { Toast.makeText(this, "请先绑定服务", 1).show(); } else { String strTicketId = this.txtTicketId.getText().toString().trim(); if(TextUtils.isEmpty(strTicketId)) { Toast.makeText(this, "请输入电影票Id", 1).show(); return; } // 4.调用IBinder对象的方法 String ticketInfo = this.ticketBinder.getTicketInfoById(Integer.parseInt(strTicketId)); this.lblTicketInfo.setText(ticketInfo); } } }
package com.shz.localservice; public class Ticket { public int Id; public String Name; public float Price; public Ticket(int id, String name, float price) { Id = id; Name = name; Price = price; } @Override public String toString() { return "您查询的电影是:"+this.Name+",票价为:"+this.Price; } }
package com.shz.localservice; public interface IService { public String getTicketInfoById(int id); }
运行效果截图