{"id":254604,"date":"2015-04-06T16:41:17","date_gmt":"2015-04-06T12:41:17","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=254604"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=254604","title":{"rendered":"Android Volley Loader. \u0414\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438"},"content":{"rendered":"<p>     \t\u0414\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0435 <a href=\"http:\/\/habrahabr.ru\/post\/254801\/\">\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u044b \u043f\u043e \u0441\u043a\u0440\u0435\u0449\u0438\u0432\u0430\u043d\u0438\u044e Volley \u0438 Loader<\/a> \u043f\u0440\u0438\u0432\u0435\u043b\u0438 \u043c\u0435\u043d\u044f \u043a \u043c\u044b\u0441\u043b\u0438 \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u0427\u0442\u043e\u0431\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0441\u044f Loader \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0438 \u0432 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u043a\u0443. \u041d\u0430 \u043f\u043e\u0434\u043e\u0431\u0438\u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0432 Picaso. \u041f\u043e\u0441\u043b\u0435 \u043f\u0430\u0440\u044b \u0432\u0435\u0447\u0435\u0440\u043e\u0432 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c\u2026<\/p>\n<p>  JSON  <\/p>\n<pre><code class=\"xml\">{ &quot;1&quot;:{&quot;name&quot;:&quot;Samsung&quot;,&quot;price&quot;:51200.6}, &quot;2&quot;:{&quot;name&quot;:&quot;Lg&quot;,&quot;price&quot;:5400.6}, &quot;3&quot;:{&quot;name&quot;:&quot;Alcatel&quot;,&quot;price&quot;:4500.6}, &quot;4&quot;:{&quot;name&quot;:&quot;iPhone&quot;,&quot;price&quot;:4800.3}, &quot;7&quot;:{&quot;name&quot;:&quot;iPad&quot;,&quot;price&quot;:2850.1} } <\/code><\/pre>\n<p>  Data  <\/p>\n<pre><code class=\"java\">public class GoodsItem {     String name;     float price; } <\/code><\/pre>\n<p>  Loader  <\/p>\n<pre><code class=\"java\">    private String url = &quot;http:\/\/192.168.1.103\/shop.json&quot;;     private static final int LOADER_GOODS_ID = 1;     Map&lt;Integer, GoodsItem&gt; mGoodsMap = new HashMap&lt;Integer, GoodsItem&gt;();     @Override     protected void onCreate(Bundle savedInstanceState) {         ...         FeedLoader.with(this).addLoader(LOADER_GOODS_ID, url, HashMap.class, new DelivererFeedLoader.Listener&lt;Map&lt;Integer, GoodsItem&gt;&gt;() {             @Override             public void onResponse(int loaderId,                  Map&lt;Integer, GoodsItem&gt; goodsMap) {                 mGoodsMap = goodsMap;                 for (Map.Entry&lt;Integer, GoodsItem&gt; entry : mGoodsMap.entrySet()) {                     Log.d(TAG , &quot;Goods item : &quot; + entry.getKey() + &quot; : &quot; + entry.getValue());                 }             }             @Override             public void onErrorResponse(VolleyError data) {                 Log.d(TAG , &quot;onErrorResponse :&quot; + data);             }         }).start(LOADER_GOODS_ID, this); <\/code><\/pre>\n<p>  <a name=\"habracut\"><\/a><\/p>\n<p>  \u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 Singleton. \u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e, \u043a\u0430\u043a \u0432 Picaso<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">FeedLoader.with(this)<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">public static FeedLoader with(Context context) {     if (singleton == null) {         synchronized (FeedLoader.class) {             if (singleton == null) {                 singleton = new FeedLoader(context);             }         }     }     return singleton; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0422\u0438\u043f\u043e\u0432 \u0438 \u041b\u0438\u0441\u0442\u043d\u0435\u0440\u0430 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 addLoader:<br \/>  <b>loaderId<\/b> \u2014 ID \u043b\u043e\u0430\u0434\u0435\u0440\u0430, \u043f\u0440\u043e\u0441\u0442\u043e \u0447\u0438\u0441\u043b\u043e<br \/>  <b>url<\/b> \u2014 \u0410\u0434\u0440\u0435\u0441 feed<br \/>  <b>loaderClazz<\/b> \u2014 \u042d\u0442\u043e \u0442\u0438\u043f \u043a\u043b\u0430\u0441\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0442\u0438\u043c \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c<br \/>  <b>DelivererFeedLoader.Listener <\/b> \u2014 Callback \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0435\u0440\u043d\u0443\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u043b\u0438 \u043e\u0448\u0438\u0431\u043a\u0430  <\/p>\n<pre><code class=\"java\">public FeedLoader addLoader(int loaderId, String url, Class&lt;?&gt; loaderClazz, DelivererFeedLoader.Listener callback){     delivererFeedLoader.loaderClazzMap.put(loaderId, loaderClazz);     delivererFeedLoader.callBackMap.put(loaderId, callback);     delivererFeedLoader.urlFeeds.put(loaderId, url);     return singleton; } <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c Loader \u0447\u0435\u0440\u0435\u0437 start(&#8230;):  <\/p>\n<pre><code class=\"java\">public void start(int loaderId, final Context context) {     Bundle bundle = new Bundle();     bundle.putParcelable(&quot;delivererFeedLoader&quot;, delivererFeedLoader);      ((FragmentActivity)context).getSupportLoaderManager().             restartLoader(loaderId, bundle, callback); } <\/code><\/pre>\n<p>  \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0447\u0435\u0442\u044b\u0440\u0435 \u0444\u0430\u0439\u043b\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Alfa  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">FeedLoader.java<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package net.appz.feedloader;  import android.content.Context; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader;  \/**  * Created by App-z.net on 04.04.15.  *\/ public class FeedLoader {      private static volatile FeedLoader singleton = null;      private Context context = null;     private boolean DEBUG = true;     private String TAG = getClass().getSimpleName();      private DelivererFeedLoader delivererFeedLoader = new DelivererFeedLoader();      public FeedLoader(Context context) {         this.context = context;     }      LoaderManager.LoaderCallbacks&lt;Object&gt; callback = new LoaderManager.LoaderCallbacks&lt;Object&gt;() {         @Override         public Loader&lt;Object&gt; onCreateLoader(int id, Bundle args) {             return new FeedLoaderWrapper(context , args);         }          @Override         public void onLoadFinished(Loader&lt;Object&gt; loader, Object data) {             delivererFeedLoader.callBackMap.get(loader.getId()).onResponse(loader.getId(), data);         }          @Override         public void onLoaderReset(Loader&lt;Object&gt; loader) {          }     };      public FeedLoader addLoader(int loaderId, String url, Class&lt;?&gt; loaderClazz, DelivererFeedLoader.Listener callback){         delivererFeedLoader.loaderClazzMap.put(loaderId, loaderClazz);         delivererFeedLoader.callBackMap.put(loaderId, callback);         delivererFeedLoader.urlFeeds.put(loaderId, url);         return singleton;     }      public void start(int loaderId, final Context context) {         Bundle bundle = new Bundle();         bundle.putParcelable(&quot;delivererFeedLoader&quot;, delivererFeedLoader);          ((FragmentActivity)context).getSupportLoaderManager().                 restartLoader(loaderId, bundle, callback);     }      public static FeedLoader with(Context context) {         if (singleton == null) {             synchronized (FeedLoader.class) {                 if (singleton == null) {                     singleton = new FeedLoader(context);                 }             }         }         return singleton;     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">FeedLoaderWrapper.java<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package net.appz.feedloader;  \/**  * Created by App-z.net on 05.04.15.  *\/  import android.content.Context; import android.os.Bundle; import android.support.v4.content.Loader; import android.util.Log;  import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.Volley;  \/**  *  * @param &lt;D&gt;  *\/ class FeedLoaderWrapper&lt;D&gt; extends Loader&lt;D&gt; {      private boolean DEBUG = true;     private String TAG = getClass().getSimpleName();      private DelivererFeedLoader delivererFeedLoader = new DelivererFeedLoader();      private RequestQueue requestQueue;      \/**      * Stores away the application context associated with context.      * Since Loaders can be used across multiple activities it's dangerous to      * store the context directly; always use {@link #getContext()} to retrieve      * the Loader's Context, don't use the constructor argument directly.      * The Context returned by {@link #getContext} is safe to use across      * Activity instances.      *      * @param context used to retrieve the application context.      *\/     public FeedLoaderWrapper(Context context, Bundle bundle) {         super(context);         delivererFeedLoader = bundle.getParcelable(&quot;delivererFeedLoader&quot;);         requestQueue = Volley.newRequestQueue(context);         \/\/ run only once         onContentChanged();     }      \/**      * Get Data      *\/     private void doRequest(Class&lt;?&gt; clazz) {         String urlFeed = delivererFeedLoader.urlFeeds.get(getId());         final GsonRequest gsonRequest = new GsonRequest(urlFeed,                 clazz,                 null,                 new Response.Listener&lt;D&gt;() {                     @Override                     public void onResponse(D data) {                         deliverResult(data);                     }                 }, new Response.ErrorListener() {             @Override             public void onErrorResponse(VolleyError volleyError) {                 if (volleyError != null)                     \/\/deliverResult(null);                     if (DEBUG) Log.e(TAG, &quot;volleyError: &quot; + volleyError.getMessage());                         delivererFeedLoader.callBackMap.get(getId()).onErrorResponse(volleyError);             }         });         requestQueue.add(gsonRequest);     }      @Override     protected void onStartLoading() {         if (takeContentChanged())             forceLoad();     }      @Override     protected void onStopLoading() {         if (DEBUG) Log.i(TAG, &quot;Loader onStopLoading()&quot;);         requestQueue.cancelAll(this);         super.onStopLoading();     }      @Override     protected void onReset() {         if (DEBUG) Log.i(TAG, &quot;Loader onReset()&quot;);         requestQueue.cancelAll(this);         super.onReset();     }      @Override     public void onForceLoad() {         super.onForceLoad();          String urlFeed = delivererFeedLoader.urlFeeds.get(getId());         if (DEBUG) Log.d(TAG, &quot;Loader onForceLoad() : feedUrl = &quot; + urlFeed);         doRequest(delivererFeedLoader.loaderClazzMap.get(getId()));     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">DelivererFeedLoader.java<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package net.appz.feedloader;  import android.os.Parcel; import android.os.Parcelable; import com.android.volley.VolleyError; import java.util.HashMap;  \/**  * Created by App-z.net on 05.04.15.  *\/ public class DelivererFeedLoader implements Parcelable {     HashMap&lt;Integer, Class&gt; loaderClazzMap = new HashMap&lt;&gt;();     HashMap&lt;Integer, Listener&gt; callBackMap = new HashMap&lt;&gt;();     HashMap&lt;Integer, String&gt; urlFeeds = new HashMap&lt;&gt;();      public DelivererFeedLoader(){}      protected DelivererFeedLoader(Parcel in) {         loaderClazzMap = (HashMap) in.readValue(HashMap.class.getClassLoader());         callBackMap = (HashMap) in.readValue(HashMap.class.getClassLoader());         urlFeeds = (HashMap) in.readValue(HashMap.class.getClassLoader());     }      @Override     public int describeContents() {         return 0;     }      @Override     public void writeToParcel(Parcel dest, int flags) {         dest.writeValue(loaderClazzMap);         dest.writeValue(callBackMap);         dest.writeValue(urlFeeds);     }      @SuppressWarnings(&quot;unused&quot;)     public static final Parcelable.Creator&lt;DelivererFeedLoader&gt; CREATOR = new Parcelable.Creator&lt;DelivererFeedLoader&gt;() {         @Override         public DelivererFeedLoader createFromParcel(Parcel in) {             return new DelivererFeedLoader(in);         }          @Override         public DelivererFeedLoader[] newArray(int size) {             return new DelivererFeedLoader[size];         }     };      public interface Listener&lt;D&gt;{         void onResponse(int loaderId, D data);         void onErrorResponse(VolleyError data);     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">GsonRequest.java<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package net.appz.feedloader;  import com.android.volley.AuthFailureError; import com.android.volley.NetworkResponse; import com.android.volley.ParseError; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.toolbox.HttpHeaderParser; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException;  import java.io.UnsupportedEncodingException; import java.util.Map;  \/**  * Created by App-z.net on 29.03.15.  *\/ public class GsonRequest&lt;T&gt; extends Request&lt;T&gt; {     private final Gson gson = new Gson();     private final Class&lt;T&gt; clazz;     private final Map&lt;String, String&gt; headers;     private final Response.Listener&lt;T&gt; listener;      \/**      * Make a GET request and return a parsed object from JSON.      *      * @param url URL of the request to make      * @param clazz Relevant class object, for Gson's reflection      * @param headers Map of request headers      *\/     public GsonRequest(String url, Class&lt;T&gt; clazz, Map&lt;String, String&gt; headers,                        Response.Listener&lt;T&gt; listener, Response.ErrorListener errorListener) {         super(Method.GET, url, errorListener);         this.clazz = clazz;         this.headers = headers;         this.listener = listener;     }      @Override     public Map&lt;String, String&gt; getHeaders() throws AuthFailureError {         return headers != null ? headers : super.getHeaders();     }      @Override     protected void deliverResponse(T response) {         listener.onResponse(response);     }      @Override     protected Response&lt;T&gt; parseNetworkResponse(NetworkResponse response) {         try {             String json = new String(                     response.data,                     HttpHeaderParser.parseCharset(response.headers));             return Response.success(                     gson.fromJson(json, clazz),                     HttpHeaderParser.parseCacheHeaders(response));         } catch (UnsupportedEncodingException e) {             return Response.error(new ParseError(e));         } catch (JsonSyntaxException e) {             return Response.error(new ParseError(e));         }     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <a href=\"https:\/\/github.com\/app-z\/FeedLoader\">\u041f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 GitHub<\/a><br \/>  <a href=\"https:\/\/github.com\/stephanenicolas\/robospice\">RoboSpice<\/a><\/p>\n<p>  \/\/ TO DO  <\/p>\n<ul>\n<li>\u041f\u043e\u043a\u0430 \u043d\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0432 FeedLoader<\/li>\n<li>\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 Loader<\/li>\n<li>Rename DelivererFeedLoader to DispatcherLoader<\/li>\n<\/ul>\n<div class=\"polling\">\n<form action=\"\/json\/polling\/\" class=\"poll\" method=\"post\">\n<div class=\"poll_title\">\u0421\u0442\u0430\u043b\u0438 \u0431\u044b \u0432\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439?<\/div>\n<p>  \t\t<input type=\"hidden\" name=\"post_id\" value=\"254989\"\/> \t\t<input type=\"hidden\" name=\"polling_question_id\" value=\"13395\"\/>  \t\t<\/p>\n<table class=\"answer\">\n<tr>\n<td class=\"input\"> \t\t\t\t\t<input type=\"radio\" id=\"vv66197\" \t\t\t\t\t\tclass=\"radio js-field-data\" \t\t\t\t\t\tname=\"variant[]\" \t\t\t\t\t\tvalue=\"66197\" \/> \t\t\t\t<\/td>\n<td class=\"label\"> \t\t\t\t\t<label for=\"vv66197\">\u0414\u0430<\/label> \t\t\t\t<\/td>\n<\/tr>\n<tr>\n<td class=\"input\"> \t\t\t\t\t<input type=\"radio\" id=\"vv66199\" \t\t\t\t\t\tclass=\"radio js-field-data\" \t\t\t\t\t\tname=\"variant[]\" \t\t\t\t\t\tvalue=\"66199\" \/> \t\t\t\t<\/td>\n<td class=\"label\"> \t\t\t\t\t<label for=\"vv66199\">\u041d\u0435\u0442<\/label> \t\t\t\t<\/td>\n<\/tr>\n<tr>\n<td class=\"input\"> \t\t\t\t\t<input type=\"radio\" id=\"vv66201\" \t\t\t\t\t\tclass=\"radio js-field-data\" \t\t\t\t\t\tname=\"variant[]\" \t\t\t\t\t\tvalue=\"66201\" \/> \t\t\t\t<\/td>\n<td class=\"label\"> \t\t\t\t\t<label for=\"vv66201\">\u0411\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0432\u0435\u0449\u044c. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0434\u0440\u0443\u0433\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a robospice<\/label> \t\t\t\t<\/td>\n<\/tr>\n<\/table>\n<p class=\"total\">\u041f\u0440\u043e\u0433\u043e\u043b\u043e\u0441\u043e\u0432\u0430\u043b\u043e 26 \u0447\u0435\u043b\u043e\u0432\u0435\u043a. \u0412\u043e\u0437\u0434\u0435\u0440\u0436\u0430\u043b\u043e\u0441\u044c 7 \u0447\u0435\u043b\u043e\u0432\u0435\u043a.<\/p>\n<\/p><\/form>\n<p class=\"for_users_only_msg\">\u0422\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043c\u043e\u0433\u0443\u0442 \u0443\u0447\u0430\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432 \u043e\u043f\u0440\u043e\u0441\u0435. <a href=\"https:\/\/habrahabr.ru\/auth\/login\/\">\u0412\u043e\u0439\u0434\u0438\u0442\u0435<\/a>, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430.<\/p>\n<\/p><\/div>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/254989\/\"> http:\/\/habrahabr.ru\/post\/254989\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>     \t\u0414\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0435 <a href=\"http:\/\/habrahabr.ru\/post\/254801\/\">\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u044b \u043f\u043e \u0441\u043a\u0440\u0435\u0449\u0438\u0432\u0430\u043d\u0438\u044e Volley \u0438 Loader<\/a> \u043f\u0440\u0438\u0432\u0435\u043b\u0438 \u043c\u0435\u043d\u044f \u043a \u043c\u044b\u0441\u043b\u0438 \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u0427\u0442\u043e\u0431\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0441\u044f Loader \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0438 \u0432 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u043a\u0443. \u041d\u0430 \u043f\u043e\u0434\u043e\u0431\u0438\u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0432 Picaso. \u041f\u043e\u0441\u043b\u0435 \u043f\u0430\u0440\u044b \u0432\u0435\u0447\u0435\u0440\u043e\u0432 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c\u2026<\/p>\n<p>  JSON  <\/p>\n<pre><code class=\"xml\">{ &quot;1&quot;:{&quot;name&quot;:&quot;Samsung&quot;,&quot;price&quot;:51200.6}, &quot;2&quot;:{&quot;name&quot;:&quot;Lg&quot;,&quot;price&quot;:5400.6}, &quot;3&quot;:{&quot;name&quot;:&quot;Alcatel&quot;,&quot;price&quot;:4500.6}, &quot;4&quot;:{&quot;name&quot;:&quot;iPhone&quot;,&quot;price&quot;:4800.3}, &quot;7&quot;:{&quot;name&quot;:&quot;iPad&quot;,&quot;price&quot;:2850.1} } <\/code><\/pre>\n<p>  Data  <\/p>\n<pre><code class=\"java\">public class GoodsItem {     String name;     float price; } <\/code><\/pre>\n<p>  Loader  <\/p>\n<pre><code class=\"java\">    private String url = &quot;http:\/\/192.168.1.103\/shop.json&quot;;     private static final int LOADER_GOODS_ID = 1;     Map&lt;Integer, GoodsItem&gt; mGoodsMap = new HashMap&lt;Integer, GoodsItem&gt;();     @Override     protected void onCreate(Bundle savedInstanceState) {         ...         FeedLoader.with(this).addLoader(LOADER_GOODS_ID, url, HashMap.class, new DelivererFeedLoader.Listener&lt;Map&lt;Integer, GoodsItem&gt;&gt;() {             @Override             public void onResponse(int loaderId,                  Map&lt;Integer, GoodsItem&gt; goodsMap) {                 mGoodsMap = goodsMap;                 for (Map.Entry&lt;Integer, GoodsItem&gt; entry : mGoodsMap.entrySet()) {                     Log.d(TAG , &quot;Goods item : &quot; + entry.getKey() + &quot; : &quot; + entry.getValue());                 }             }             @Override             public void onErrorResponse(VolleyError data) {                 Log.d(TAG , &quot;onErrorResponse :&quot; + data);             }         }).start(LOADER_GOODS_ID, this); <\/code><\/pre>\n<p>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-254604","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/254604","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=254604"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/254604\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=254604"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=254604"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=254604"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}