利用广播调用后台服务方法并根据方法返回的内容更新UI
一、UI布局代码
<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" > <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>
二、MainActivity代码
package com.shz.localservice; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import com.shz.callservicebybroadcastreceiver.R; public class MainActivity extends Activity { /** * 通过广播调用后台服务并更新UI 实现步骤: * 1.前台Activity发出一个自定义广播A(Action:com.shz.getticketinfo),后台服务需注册该广播A进行监听。 * 2.后台服务监听到该广播A之后 * ,调用自己内部方法获取电影票信息,并发出一个自定义广播B(Action:com.shz.sendticketinfo)。 * 3.前台Activity需注册该广播B进行监听,获取广播B中的内容更新UI。 */ private EditText txtTicketId; private TextView lblTicketInfo; private ReceiveTicketInfoReceiver receiver; @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); // 开启服务 Intent intent = new Intent(this, TicketService.class); startService(intent); // 注册后台服务发出的广播,该广播包含电影票信息 receiver = new ReceiveTicketInfoReceiver(); IntentFilter filter = new IntentFilter("com.shz.sendticketinfo"); registerReceiver(receiver, filter); } /** * 该接收者用于监听后台服务发送出的广播B,并更新UI * * @author SHZ * */ private class ReceiveTicketInfoReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String ticketInfo = intent.getStringExtra("TicketInfo"); lblTicketInfo.setText(ticketInfo); } } public void callServiceMethod(View view) { String strTicketId = this.txtTicketId.getText().toString().trim(); if(TextUtils.isEmpty(strTicketId)) { Toast.makeText(this, "请输入电影票Id", 1).show(); return; } // 发送一个自定义广播,后台服务会监听该广播,并调用服务方法获取电影票信息 Intent intent = new Intent(); intent.setAction("com.shz.getticketinfo"); intent.putExtra("TicketId", Integer.parseInt(strTicketId)); sendBroadcast(intent); } @Override protected void onDestroy() { unregisterReceiver(receiver); stopService(new Intent(this, TicketService.class)); super.onDestroy(); } }
三、服务代码
package com.shz.localservice; import java.util.ArrayList; import java.util.List; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; 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; private SendTicketInfoReceiver receiver; @Override public IBinder onBind(Intent intent) { Log.i(TAG, "onBind 服务绑定成功"); return null; } @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)); // 注册前台Activity发出的广播,该广播是请求电影票信息 receiver = new SendTicketInfoReceiver(); IntentFilter filter = new IntentFilter("com.shz.getticketinfo"); registerReceiver(receiver, filter); } @Override public void onDestroy() { super.onDestroy(); Log.i(TAG, "onDestroy 服务销毁成功"); unregisterReceiver(receiver); } 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; } } /** * 该接收者用于接收前台Activity发出的广播A,获取A中的TicketId,调用内部方法查询电影票信息,并发出广播B * @author SHZ * */ private class SendTicketInfoReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { int ticketId = intent.getIntExtra("TicketId", 0); String ticketInfo = getTicketInfo(ticketId); // 发送本服务的一个自定义广播,前台Activity会监听该广播获取电影票信息 Intent sendIntent = new Intent(); sendIntent.setAction("com.shz.sendticketinfo"); sendIntent.putExtra("TicketInfo", ticketInfo); sendBroadcast(sendIntent); } } }
四、其他相关代码
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; } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.shz.callservicebybroadcastreceiver" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.shz.localservice.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="com.shz.localservice.TicketService"></service> </application> </manifest>
效果截图: