RoboSpice. Используем Google Http Client

| 12.02.2015

В предыдущей статье мы разбирали пример простейшего запроса к внешнему сайту для получения текста с помощью RoboSpice. Мы использовали класс SimpleTextRequest, в котором имеется метод loadDataFromNetwork(), выполняющий основную работу загрузки текста.

@Override
public String loadDataFromNetwork() throws Exception {
    try {
        Ln.d("Call web service " + url);
        return IOUtils.toString(new InputStreamReader(new URL(url).openStream(), CharEncoding.UTF_8));
    } catch (final MalformedURLException e) {
        Ln.e(e, "Unable to create URL");
        throw e;
    } catch (final IOException e) {
        Ln.e(e, "Unable to download content");
        throw e;
    }
}

В общем-то, мы видим, что работы с внешним ресурсом используется стандартная библиотека IO. Давайте посмотрим, как мы можем использовать для запроса библиотеку Google Http Client. Для этого нам нужно переопределить метод loadDataFromNetwork() (для этого мы создадим новый класс, который унаследуем от GoogleHttpClientSpiceRequest).

Итак, настройки зависимостей:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.+'
    compile 'com.octo.android.robospice:robospice-google-http-client:1.4.11'
}

Строковые ресурсы res/values/strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">RoboSpice Example</string>
    <string name="action_settings">Settings</string>
    <string name="title_activity_sample_spice">SampleSpiceActivity</string>
    <string name="textview_text">textview_text</string>
</resources>

Код лэйаута res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/txtV"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:ellipsize="marquee"
        android:singleLine="true"
        android:text="textview_text" />

</LinearLayout>

Класс сервиса SampleSpiceService остался прежним:

package ru.androiddocs.robospiceexample;

import android.app.Application;

import com.octo.android.robospice.SpiceService;
import com.octo.android.robospice.persistence.CacheManager;
import com.octo.android.robospice.persistence.exception.CacheCreationException;
import com.octo.android.robospice.persistence.string.InFileStringObjectPersister;

public class SampleSpiceService extends SpiceService {

    @Override
    public CacheManager createCacheManager(Application application) throws CacheCreationException {
        CacheManager cacheManager = new CacheManager();

        InFileStringObjectPersister inFileStringObjectPersister =
                new InFileStringObjectPersister(application);

        cacheManager.addPersister(inFileStringObjectPersister);

        return cacheManager;
    }

    @Override
    public int getThreadCount() {
        return 3;
    }
}

Базовый класс BaseSpiceActivity также не меняем:

package ru.androiddocs.robospiceexample;

import android.app.Activity;

import com.octo.android.robospice.SpiceManager;


public abstract class BaseSpiceActivity extends Activity {
    private SpiceManager spiceManager = new SpiceManager(SampleSpiceService.class);

    @Override
    protected void onStart() {
        spiceManager.start(this);
        super.onStart();
    }

    @Override
    protected void onStop() {
        spiceManager.shouldStop();
        super.onStop();
    }

    protected SpiceManager getSpiceManager() {
        return spiceManager;
    }

}

Добавим класс MyHttpRequest, который унаследуем от GoogleHttpClientSpiceRequest:

package ru.androiddocs.robospiceexample;

import java.io.IOException;

import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.octo.android.robospice.request.googlehttpclient.GoogleHttpClientSpiceRequest;

public class MyHttpRequest extends GoogleHttpClientSpiceRequest<String> {

    private String baseUrl;

    public MyHttpRequest(String url) {
        super(String.class);
        this.baseUrl = url;
    }

    @Override
    public String loadDataFromNetwork() throws IOException {

        HttpTransport transport = new NetHttpTransport();
        HttpRequestFactory factory = transport.createRequestFactory(new MyHttpRequestInitializer());
        HttpRequest request = factory.buildGetRequest(new GenericUrl(baseUrl));

        return request.execute().parseAsString();
    }


    private class MyHttpRequestInitializer implements HttpRequestInitializer {

        MyHttpRequestInitializer() {}

        public void initialize(HttpRequest request) throws IOException {
            // тут можно добавить каких-то параметров к request, например, парсер json
            // request.setParser(new JacksonFactory().createJsonObjectParser()));
        }
    }

}

Как видим, конструктор принимает url, с которого будут «считываться» данные. Весь процесс происходит в методе loadDataFromNetwork(), а результат парсим в виде обычной строки (json сейчас не разбираем). Также, думаю, вы уже обратили внимание, что при создании HttpRequestFactory мы используем внутренний класс MyHttpRequestInitializer, где в методе initialize() при желании можно установить парсер json. В нашем примере задача показать сам процесс загрузки данных, поэтому, чтобы код не усложнять, json пока не разбираем.

Теперь основное Активити — SampleSpiceActivity.java

package ru.androiddocs.robospiceexample;

import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

import com.octo.android.robospice.persistence.DurationInMillis;
import com.octo.android.robospice.persistence.exception.SpiceException;
import com.octo.android.robospice.request.listener.RequestListener;

public class SampleSpiceActivity extends BaseSpiceActivity {

    private TextView mTxtView;
    private MyHttpRequest txtRequest;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTxtView = (TextView) findViewById(R.id.txtV);

        txtRequest = new MyHttpRequest("http://androiddocs.ru/api/friends.json");
    }

    @Override
    protected void onStart() {
        super.onStart();

        getSpiceManager().execute(txtRequest, "txt", DurationInMillis.ONE_MINUTE,
                new TextRequestListener());
    }

    public final class TextRequestListener implements RequestListener<String> {

        @Override
        public void onRequestFailure(SpiceException spiceException) {
            Toast.makeText(SampleSpiceActivity.this, "failure", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onRequestSuccess(final String result) {
            Toast.makeText(SampleSpiceActivity.this, "success", Toast.LENGTH_SHORT).show();
            mTxtView.setText(result);
        }
    }
}

Файл манифеста:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ru.androiddocs.robospiceexample" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <service
            android:name=".SampleSpiceService"
            android:enabled="true"
            android:exported="true" >
        </service>

        <activity
            android:name=".SampleSpiceActivity"
            android:label="@string/title_activity_sample_spice" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Собственно, все. Запускаем и получаем тот же результат.

RoboSpice. Используем Google Http Client

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*