intentservice_使用intentService在Android中使用Webservice

intentservice

intentservice

在本文中,我将解释如何使用IntentService来使用Restful Webservice。 我们知道我们可以使用Volley lib或简单的Http客户端直接在UI中使用Webservice,但是在某些情况下,我们更喜欢在Android Service中使用Webservice。

我们知道,Android Service比Android Activity的寿命更长,并且即使应用UI不再可用,如果我们希望完成任务,我们也应该使用Service 。 例如,我们可以考虑下载情况:假设我们要从远程服务器下载一些信息; 我们可以在用户界面(即活动)中进行操作,但是例如,如果用户移动到另一个应用程序,则下载将被中断。 如果我们希望即使该应用程序不再处于活动状态,也可以继续下载,则可以使用Service。

IntentService说明

当我们要使用Web服务时,我们必须意识到与服务器联系并获得响应所需的时间可能会很长。 即使我们执行此逻辑是一个单独的服务,该服务本身也会在主线程中运行,因此调用活动可能会滞后,等待该服务的响应,而OS可能会杀死它并显示令人讨厌的ANR消息。 我们可以避免在服务内部处理单独的线程时避免此问题,但是Android SDK提供了一个专门类,该类派生自Service类,称为IntentService,其定义为(来自Android API文档):

“ IntentService是Service的基类,可按需处理异步请求(表示为Intent )。 客户端通过startService(Intent)调用发送请求; 该服务将根据需要启动,使用工作线程依次处理每个Intent,并在工作耗尽时自行停止。这种“工作队列处理器”模式通常用于从应用程序的主线程卸载任务。”

考虑到繁重的工作是在单独的线程中完成的,因此我们不知道何时完成,并且调用Activity也不知道。 我们将描述如何在服务从远程Web服务检索数据时取回信息。

创建IntentService

例如,我们将使用Yahoo! 财务服务检索股票的当前卖价和买价。 最后,我们将构建一个像这样的应用程序:

android_webservice_intentservice [4]

第一步是创建服务:

public class QuoteService extends IntentService {

    @Override
    protected void onHandleIntent(Intent intent) {
         // Here we do the heavy work
    }
}

在第4行的onHandleIntent我们进行了“繁重的工作”,因此我们调用远程Web服务并解析响应。 在这种情况下,我们可以简单地使用XmlPullParser来解析数据:

// Here we retrieve the stock quote using Yahoo! Finance
Log.d("Srv", "Get stock");
String url = YAHOO_FINANCE_URL.replaceAll("#sym#", stock.getSymbol());
try {
    HttpURLConnection con = (HttpURLConnection) ( new URL(url)).openConnection();
    con.setRequestMethod("GET");
    con.connect();
    InputStream is = con.getInputStream();

    // Start parsing XML
    XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
    parser.setInput(is, null);
    int event = parser.getEventType();
    String tagName = null;
    String currentTag = null;
    Stock stockResult = new Stock();

    while (event != XmlPullParser.END_DOCUMENT) {
        tagName = parser.getName();
        Log.d("Srv", "Tag:" + tagName);
        if (event == XmlPullParser.START_TAG) {
            currentTag = tagName;
        }
        else if (event == XmlPullParser.TEXT) {
            if ("ASK".equalsIgnoreCase(currentTag)) 
                //
            else if    ("BID".equalsIgnoreCase(currentTag)) {                        
                //
            }
        }

        event = parser.next();

    }

} catch (Exception e) {
    e.printStackTrace();
}

然后,在Manifest.xml中定义我们的服务:

<service android:name=".QuoteService" />

活动:Web服务客户端

下一步是创建调用服务的客户端活动。 我们正在使用IntentService,然后调用Activity调用该服务,然后将其忘记。 该活动非常简单,因为用户一旦单击“获取报价!” 按钮,我们使用以下命令调用服务:

startService(service_intent);

无论如何,我们应该考虑两个方面:

  1. 我们如何将数据传递给服务
  2. 我们如何从服务中获取数据并在UI中显示信息

为了将数据传递给服务,我们可以创建一个简单的java类,该类包含股票代码和我们希望在获得响应时由服务填充的值。 我们的班级应该是Parcelable班级:

public class Stock implements Parcelable {

    private String symbol;
    private double askValue;
    private double bidValue;

    public Stock() {}

    public Stock(String symbol, double askValue, double bidValue) {
        this.symbol = symbol;
        this.askValue = askValue;
        this.bidValue = bidValue;
    }

    // get and set method

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // We write the stock information in the parcel
        dest.writeString(symbol);
        dest.writeDouble(askValue);
        dest.writeDouble(bidValue);
    }

    public static final Creator<Stock> CREATOR = new Creator<Stock>() {

        @Override
        public Stock createFromParcel(Parcel source) {
            Stock stock = new Stock();
            stock.setSymbol(source.readString());
            stock.setAskValue(source.readDouble());
            stock.setBidValue(source.readDouble());
            return stock;
        }

        @Override
        public Stock[] newArray(int size) {
            return new Stock[0];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }
}

在第18和25行,我们实现了封送和取消封送我们的类所需的两种方法。

使用ResultReceiver从服务中检索数据

另一个有趣的方面是我们如何从IntentService取回值。 正如我们已经知道的那样,调用活动不会等待结果,因此我们必须寻找另一种方法。 一般来说,有多种方法可以解决此问题,在本文中,我将解释如何使用ResultReceiver 。 我认为这种方法非常简单且优雅。

第一步是创建一个扩展ResultReceiver的类,我们将其称为QuoteServiceReceiver

public class QuoteServiceReceiver extends ResultReceiver {

    private Listener listener;

    public QuoteServiceReceiver(Handler handler) {
        super(handler);        
    }

    public void setListener(Listener listener) {
        this.listener = listener;
    }

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        if (listener != null)
            listener.onReceiveResult(resultCode, resultData);
    }

    public static interface Listener {
        void onReceiveResult(int resultCode, Bundle resultData);
    }

}

这个课很简单。 在第19行,我们定义了调用活动必须实现的接口,以便在数据可用时得到通知。 在此接口中,我们定义了一个Bundle,用于保存检索到的数据。 然后在第14行,我们重写onReceiveResult并调用在先前接口中定义的回调方法。

从客户端的角度(因此我们的Activity),我们只需要实现定义的接口并将QuoteServiceReceiver传递给IntentService:

private Intent createCallingIntent(Stock stock) {
    Intent i = new Intent(this, QuoteService.class);
    QuoteServiceReceiver receiver = new QuoteServiceReceiver(new Handler());
    receiver.setListener(this);        
    i.putExtra("rec", receiver);
    i.putExtra("stock", stock);
    return i;
}

当我们致电服务时:

startService(createCallingIntent(stock));

..和回调方法中:

@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
    Stock stock = resultData.getParcelable("stock");
    Log.d("Srv", "Stock ["+stock+"]");

    askValue.setText("" + stock.getAskValue());
    bidValue.setText("" + stock.getBidValue());
}

..在这里,我们使用接收到的数据更新UI。

在使用远程Web服务的服务中:

@Override
protected void onHandleIntent(Intent intent) {

    Stock stock = intent.getParcelableExtra("stock");
    final ResultReceiver rec = (ResultReceiver) intent.getParcelableExtra("rec");
    ....
    // When data is ready
   if    ("BID".equalsIgnoreCase(currentTag)) {                        
          stockResult.setBidValue(Double.parseDouble(parser.getText()));
          Bundle b = new Bundle();
          b.putParcelable("stock", stockResult);
          rec.send(0, b);
    }
    ....
}

翻译自: https://www.javacodegeeks.com/2014/04/consume-webservice-in-android-using-intentservice.html

intentservice

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值